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

Launch Arguments - the mysteries

Avatar for Marin Usalj 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.

Avatar for Marin Usalj

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