Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Launch Arguments - the mysteries

Marin Usalj
November 08, 2016

Launch Arguments - the mysteries

A talk on launch arguments in iOS / OSX environments.
Uncovers some undocumented behaviors and advanced usage.

Marin Usalj

November 08, 2016
Tweet

More Decks by Marin Usalj

Other Decks in Programming

Transcript

  1. May 15, 2017 | MARIN USALJ $ ls -la $

    git commit -a -m 'yolo' Process arguments
  2. May 15, 2017 | MARIN USALJ $ ls -la $

    git commit -a -m 'yolo' Process arguments
  3. May 15, 2017 | MARIN USALJ $ ls -la $

    git commit -a -m 'yolo' Process arguments
  4. May 15, 2017 | MARIN USALJ $ ls -la $

    git commit -a -m 'yolo' Process arguments
  5. May 15, 2017 | MARIN USALJ $ ls -la $

    git commit -a -m 'yolo' Process arguments
  6. May 15, 2017 | MARIN USALJ $ ls -la $

    git commit -a -m 'yolo' Process arguments
  7. May 15, 2017 | MARIN USALJ Used by exec() family

    of functions (execve on OSX) Process Arguments
  8. May 15, 2017 | MARIN USALJ Used by exec() family

    of functions (execve on OSX) Launching binaries, scripts with #! Process Arguments
  9. May 15, 2017 | MARIN USALJ Used by exec() family

    of functions (execve on OSX) Launching binaries, scripts with #! In C-family of languages, main(argc, argv) Process Arguments
  10. May 15, 2017 | MARIN USALJ +(id)launchParametersWithSchemeIde ntifier: launcherIdentifier: debuggerIdentifier:

    launchStyle: runnableLocation: debugProcessAsUID: workingDirectory: commandLineArgs: environmentVariables: architecture: platformIdentifier: buildConfiguration: buildableProduct: Launching, Xcode style deviceAppDataPackage: allowLocationSimulation: locationScenarioReference: routingCoverageFileReference: enableOpenGLFrameCaptureMode: enableOpenGLPerformanceAnalysisMo de: simulatorIPhoneDisplay: simulatorIPadDisplay: debugXPCServices: additionalXPCServicesToDebug: internalIOSLaunchStyle: internalIOSSubstitutionApp: launchAutomaticallySubstyle:
  11. May 15, 2017 | MARIN USALJ There are a number

    of options that can be passed into a target’s scheme to enable useful debugging behavior, but like a fast food secret menu, they’re obscure and widely unknown. MATTT THOMPSON, NSHIPSTER
  12. May 15, 2017 | MARIN USALJ In most programming environments,

    you handle arguments by yourself How does this work?
  13. May 15, 2017 | MARIN USALJ In most programming environments,

    you handle arguments by yourself Bash: getopt, getopts How does this work?
  14. May 15, 2017 | MARIN USALJ In most programming environments,

    you handle arguments by yourself Bash: getopt, getopts Ruby: OptionParser (and n^2345 others) How does this work?
  15. May 15, 2017 | MARIN USALJ In most programming environments,

    you handle arguments by yourself Bash: getopt, getopts Ruby: OptionParser (and n^2345 others) Python: argparse How does this work?
  16. May 15, 2017 | MARIN USALJ Arguments are parsed by

    Cocoa Injected on top of NSUserDefaults Parsing in Cocoa
  17. May 15, 2017 | MARIN USALJ Arguments are parsed by

    Cocoa Injected on top of NSUserDefaults No need to store a value into NSUserDefaults to read it from args Parsing in Cocoa
  18. May 15, 2017 | MARIN USALJ Arguments are parsed by

    Cocoa Injected on top of NSUserDefaults No need to store a value into NSUserDefaults to read it from args Anything stored in NSUserDefaults can be overridden Parsing in Cocoa
  19. May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app

    Launch args conference = SwiftSummit conference = NSSpain speaker = Marin
  20. May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app

    Launch args conference = SwiftSummit conference = NSSpain speaker = Marin objectForKey: "speaker"
  21. May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app

    Launch args conference = SwiftSummit conference = NSSpain speaker = Marin objectForKey: "speaker" "Marin"
  22. May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app

    Launch args conference = SwiftSummit conference = NSSpain speaker = Marin objectForKey: "conference" objectForKey: "speaker" "Marin"
  23. May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app

    Launch args conference = SwiftSummit conference = NSSpain speaker = Marin objectForKey: "conference" "SwiftSummit" objectForKey: "speaker" "Marin"
  24. May 15, 2017 | MARIN USALJ First approach: UIAutomation with

    a hidden server selector Bring up UI, type URI letter by letter Lyft's use case
  25. May 15, 2017 | MARIN USALJ First approach: UIAutomation with

    a hidden server selector Bring up UI, type URI letter by letter Lyft's use case
  26. May 15, 2017 | MARIN USALJ Recompile the app with

    hardcoded server address Given each compilation is ~5 minutes, this would waste at least 50 CI minutes for each developer push. Recompile?
  27. May 15, 2017 | MARIN USALJ Inject a file in

    the bundle after compilation Almost a viable solution, requires adding specific code for reading the bundle and overriding our servers. Inject a file?
  28. May 15, 2017 | MARIN USALJ Launch the app with

    arguments overriding server endpoints Challenge: server environment stored as a nested Dictionary More than one endpoint to override (analytics for example) Launch arguments?
  29. May 15, 2017 | MARIN USALJ "navigation": "Waze", "servers": {

    "api": "https://api.dev.lyft.com", "analytics": "https://analytics.dev.lyft.com" } Launch arguments?
  30. May 15, 2017 | MARIN USALJ $ lyft -servers.api "http://..."

    \ -servers.analytics "http://..." \ Key paths?
  31. May 15, 2017 | MARIN USALJ $ lyft -navigation Waze

    -servers '{ "foo": "bar" }' JSON?
  32. May 15, 2017 | MARIN USALJ $ lyft -servers '{

    api = https://api.staging.lyft.com; analytics = https://analytics.staging.lyft.com; lastOpened = 2016-09-18T01:29:01Z; }' -conference FrenchKit -speaker 'Marin Usalj' NeXTSTEP plists
  33. May 15, 2017 | MARIN USALJ $ lyft -servers '{

    api = https://api.staging.lyft.com; analytics = https://analytics.staging.lyft.com; lastOpened = 2016-09-18T01:29:01Z; }' -conference FrenchKit -speaker 'Marin Usalj' NeXTSTEP plists
  34. May 15, 2017 | MARIN USALJ $ lyft -servers 'yolo'

    Built in XML reader 1. Try to parse XML from 'yolo' 2. Try to parse Plist from 'yolo' 3. Just String('yolo')
  35. May 15, 2017 | MARIN USALJ $ lyft -servers 'yolo'

    Built in XML reader 1. Try to parse XML from 'yolo' 2. Try to parse Plist from 'yolo' 3. Just String('yolo')
  36. May 15, 2017 | MARIN USALJ $ lyft -servers 'yolo'

    Built in XML reader 1. Try to parse XML from 'yolo' 2. Try to parse Plist from 'yolo' 3. Just String('yolo')
  37. May 15, 2017 | MARIN USALJ Overwriting values after launch

    won't work after app launch Watch out on places where you're reading / writing to NSUserDefaults Gotchas
  38. May 15, 2017 | MARIN USALJ UserDefaults is a key-value

    Store with String keys Value types: String, Data, Number, Date, Array, and Dictionary Gotchas
  39. May 15, 2017 | MARIN USALJ open func string(forKey defaultName:

    String) -> String? open func array(forKey defaultName: String) -> [Any]? open func dictionary(forKey defaultName: String) -> [String : Any]? open func data(forKey defaultName: String) -> Data? open func stringArray(forKey defaultName: String) -> [String]? open func integer(forKey defaultName: String) -> Int open func float(forKey defaultName: String) -> Float open func double(forKey defaultName: String) -> Double open func bool(forKey defaultName: String) -> Bool open func url(forKey defaultName: String) -> URL? UserDefaults helpers
  40. May 15, 2017 | MARIN USALJ /*! -integerForKey: is equivalent

    to -objectForKey:, except that it converts the returned value to an NSInteger. If the value is an NSNumber, the result of - integerValue will be returned. If the value is an NSString, it will be converted to NSInteger if possible. If the value is a boolean, it will be converted to either 1 for YES or 0 for NO. If the value is absent or can't be converted to an integer, 0 will be returned. */ Gotchas
  41. May 15, 2017 | MARIN USALJ XML tags CoreFoundation type

    XML Tag Storage format CFString <string> UTF-8 encoded string CFNumber <real>, <integer> Decimal string CFBoolean <true/>, <false/> No data (tag only) CFDate <date> ISO 8601 formatted string CFData <data> Base64 encoded data CFArray <array> Can contain any number of child elements CFDictionary <dict> Alternating tags and plist element tags
  42. May 15, 2017 | MARIN USALJ https://developer.apple.com/library/ios/recipes/xcode_help-scheme_editor/Articles/ SchemeRun.html https://en.wikipedia.org/wiki/Property_list http://linux.die.net/man/2/execve

    http://nshipster.com/launch-arguments-and-environment-variables/ http://useyourloaf.com/blog/using-launch-arguments-to-test-localizations/#disqus_thread http://www.manpagez.com/man/3/execv/ References