Share
Embed
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
Transcript
74 slides
-
May 15, 2017 | MARIN USALJ Process Arguments Advanced usage
Gotchas Agenda -
May 15, 2017 | MARIN USALJ $ ls -la $
git commit -a -m 'yolo' Process arguments -
May 15, 2017 | MARIN USALJ $ ls -la $
git commit -a -m 'yolo' Process arguments -
May 15, 2017 | MARIN USALJ $ ls -la $
git commit -a -m 'yolo' Process arguments -
May 15, 2017 | MARIN USALJ $ ls -la $
git commit -a -m 'yolo' Process arguments -
May 15, 2017 | MARIN USALJ $ ls -la $
git commit -a -m 'yolo' Process arguments -
May 15, 2017 | MARIN USALJ $ ls -la $
git commit -a -m 'yolo' Process arguments -
May 15, 2017 | MARIN USALJ Used by exec() family
of functions (execve on OSX) Process Arguments -
May 15, 2017 | MARIN USALJ Used by exec() family
of functions (execve on OSX) Launching binaries, scripts with #! Process Arguments -
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 -
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: -
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 -
May 15, 2017 | MARIN USALJ In most programming environments,
you handle arguments by yourself How does this work? -
May 15, 2017 | MARIN USALJ In most programming environments,
you handle arguments by yourself Bash: getopt, getopts How does this work? -
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? -
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? -
May 15, 2017 | MARIN USALJ In Cocoa, there's a
little bit of -
May 15, 2017 | MARIN USALJ Arguments are parsed by
Cocoa Parsing in Cocoa -
May 15, 2017 | MARIN USALJ Arguments are parsed by
Cocoa Injected on top of NSUserDefaults Parsing in Cocoa -
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 -
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 -
May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app
conference = NSSpain speaker = Marin -
May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app
Launch args conference = SwiftSummit conference = NSSpain speaker = Marin -
May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app
Launch args conference = SwiftSummit conference = NSSpain speaker = Marin objectForKey: "speaker" -
May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app
Launch args conference = SwiftSummit conference = NSSpain speaker = Marin objectForKey: "speaker" "Marin" -
May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app
Launch args conference = SwiftSummit conference = NSSpain speaker = Marin objectForKey: "conference" objectForKey: "speaker" "Marin" -
May 15, 2017 | MARIN USALJ NSUserDefaults lookup NSUserDefaults app
Launch args conference = SwiftSummit conference = NSSpain speaker = Marin objectForKey: "conference" "SwiftSummit" objectForKey: "speaker" "Marin" -
May 15, 2017 | MARIN USALJ What do I do
with this? -
May 15, 2017 | MARIN USALJ Lyft's use case ?
? ? ? ? ? ? ? -
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 -
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 -
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? -
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? -
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? -
May 15, 2017 | MARIN USALJ "navigation": "Waze", "servers": {
"api": "https://api.dev.lyft.com", "analytics": "https://analytics.dev.lyft.com" } Launch arguments? -
May 15, 2017 | MARIN USALJ $ lyft -servers.api "http://..."
\ -servers.analytics "http://..." \ Key paths? -
May 15, 2017 | MARIN USALJ $ lyft -navigation Waze
-servers '{ "foo": "bar" }' JSON? -
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 -
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 -
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') -
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') -
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') -
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 -
May 15, 2017 | MARIN USALJ UserDefaults is a key-value
Store with String keys Value types: String, Data, Number, Date, Array, and Dictionary Gotchas -
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 -
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 -
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 -
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