Launch Arguments - the mysteries

Launch Arguments - the mysteries

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

1a8210be06c7e4e4add04eb95ea7964c?s=128

Marin Usalj

November 08, 2016
Tweet

Transcript

  1. May 15, 2017 | Marin Usalj Launch argumentsthe mysteries

  2. May 15, 2017 | MARIN USALJ @supermarin supermar.in Marin Usalj

  3. May 15, 2017 | MARIN USALJ Author of Alcatraz, xcpretty

  4. May 15, 2017 | MARIN USALJ

  5. May 15, 2017 | MARIN USALJ Agenda

  6. May 15, 2017 | MARIN USALJ Process Arguments Agenda

  7. May 15, 2017 | MARIN USALJ Process Arguments Advanced usage

    Agenda
  8. May 15, 2017 | MARIN USALJ Process Arguments Advanced usage

    Gotchas Agenda
  9. Process arguments

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

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

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

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

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

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

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

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

    of functions (execve on OSX) Launching binaries, scripts with #! Process Arguments
  18. 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
  19. 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:
  20. May 15, 2017 | MARIN USALJ Demo ⏲

  21. 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
  22. May 15, 2017 | MARIN USALJ How does this work?

  23. May 15, 2017 | MARIN USALJ In most programming environments,

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

    you handle arguments by yourself Bash: getopt, getopts How does this work?
  25. 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?
  26. 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?
  27. May 15, 2017 | MARIN USALJ How does this work?

  28. May 15, 2017 | MARIN USALJ In Cocoa, there's a

    little bit of
  29. May 15, 2017 | MARIN USALJ Arguments are parsed by

    Cocoa Parsing in Cocoa
  30. May 15, 2017 | MARIN USALJ Arguments are parsed by

    Cocoa Injected on top of NSUserDefaults Parsing in Cocoa
  31. 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
  32. 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
  33. May 15, 2017 | MARIN USALJ NSUserDefaults lookup app

  34. May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app

    conference = NSSpain speaker = Marin
  35. May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app

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

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

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

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

    Launch args conference = SwiftSummit conference = NSSpain speaker = Marin objectForKey: "conference" "SwiftSummit" objectForKey: "speaker" "Marin"
  40. May 15, 2017 | MARIN USALJ What do I do

    with this?
  41. May 15, 2017 | MARIN USALJ Changing app behavior without

    recompiling
  42. May 15, 2017 | MARIN USALJ Lyft's use case

  43. May 15, 2017 | MARIN USALJ Lyft's use case

  44. May 15, 2017 | MARIN USALJ Lyft's use case

  45. May 15, 2017 | MARIN USALJ Lyft's use case

  46. May 15, 2017 | MARIN USALJ Lyft's use case ?

    ? ? ? ? ? ? ?
  47. 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
  48. 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
  49. May 15, 2017 | MARIN USALJ Lyft's use case

  50. May 15, 2017 | MARIN USALJ Lyft's use case

  51. 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?
  52. 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?
  53. 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?
  54. May 15, 2017 | MARIN USALJ "navigation": "Waze", "servers": {

    "api": "https://api.dev.lyft.com", "analytics": "https://analytics.dev.lyft.com" } Launch arguments?
  55. Advanced usage

  56. May 15, 2017 | MARIN USALJ $ lyft -servers.api "http://..."

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

    -servers '{ "foo": "bar" }' JSON?
  58. May 15, 2017 | MARIN USALJ Quiz ⏲

  59. May 15, 2017 | MARIN USALJ

  60. May 15, 2017 | MARIN USALJ

  61. 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
  62. 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
  63. 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')
  64. 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')
  65. 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')
  66. Gotchas

  67. 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
  68. May 15, 2017 | MARIN USALJ UserDefaults is a key-value

    Store with String keys Value types: String, Data, Number, Date, Array, and Dictionary Gotchas
  69. 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
  70. 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
  71. 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
  72. May 15, 2017 | MARIN USALJ Thanks LYFT, IDA &

    BEREN
  73. May 15, 2017 | MARIN USALJ We are hiring!

  74. 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