├── Source ├── .gitignore ├── version.h ├── nsprintf.h ├── NSString+expandPath.h ├── NSString+expandPath.m ├── main.m ├── iPhoneSimulator.h ├── nsprintf.m └── iPhoneSimulator.m ├── .gitignore ├── ios-sim.xcodeproj ├── .gitignore └── project.pbxproj ├── ios-sim_Prefix.pch ├── README.md ├── README.template.md ├── LICENSE ├── Rakefile └── iPhoneSimulatorRemoteClient └── iPhoneSimulatorRemoteClient.h /Source/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | *.swp 3 | -------------------------------------------------------------------------------- /Source/version.h: -------------------------------------------------------------------------------- 1 | #define IOS_SIM_VERSION "1.1" -------------------------------------------------------------------------------- /ios-sim.xcodeproj/.gitignore: -------------------------------------------------------------------------------- 1 | *.pbxuser 2 | *.mode1v3 3 | *.perspectivev3 4 | 5 | -------------------------------------------------------------------------------- /Source/nsprintf.h: -------------------------------------------------------------------------------- 1 | int nsvfprintf (FILE *stream, NSString *format, va_list args); 2 | int nsfprintf (FILE *stream, NSString *format, ...); 3 | int nsprintf (NSString *format, ...); 4 | -------------------------------------------------------------------------------- /ios-sim_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'iphonesim' target in the 'iphonesim' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Source/NSString+expandPath.h: -------------------------------------------------------------------------------- 1 | /* 2 | * See the LICENSE file for the license on the source code in this file. 3 | */ 4 | 5 | #import 6 | 7 | @interface NSString (ExpandPath) 8 | 9 | - (NSString *)expandPath; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Source/NSString+expandPath.m: -------------------------------------------------------------------------------- 1 | /* 2 | * See the LICENSE file for the license on the source code in this file. 3 | */ 4 | 5 | #import "NSString+expandPath.h" 6 | 7 | @implementation NSString (ExpandPath) 8 | 9 | - (NSString *)expandPath { 10 | if ([self isAbsolutePath]) { 11 | return [self stringByStandardizingPath]; 12 | } else { 13 | NSString *cwd = [[NSFileManager defaultManager] currentDirectoryPath]; 14 | return [[cwd stringByAppendingPathComponent:self] stringByStandardizingPath]; 15 | } 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Source/main.m: -------------------------------------------------------------------------------- 1 | /* Author: Landon Fuller 2 | * Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc. 3 | * All rights reserved. 4 | * 5 | * See the LICENSE file for the license on the source code in this file. 6 | */ 7 | 8 | #import 9 | 10 | #import "iPhoneSimulator.h" 11 | 12 | /* 13 | * Runs the iPhoneSimulator backed by a main runloop. 14 | */ 15 | int main (int argc, char *argv[]) { 16 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 17 | iPhoneSimulator *sim = [[iPhoneSimulator alloc] init]; 18 | 19 | /* Execute command line handler */ 20 | [sim runWithArgc: argc argv: argv]; 21 | 22 | /* Run the loop to handle added input sources, if any */ 23 | [[NSRunLoop mainRunLoop] run]; 24 | 25 | [pool release]; 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Source/iPhoneSimulator.h: -------------------------------------------------------------------------------- 1 | /* Author: Landon Fuller 2 | * Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc. 3 | * All rights reserved. 4 | * 5 | * See the LICENSE file for the license on the source code in this file. 6 | */ 7 | 8 | #import 9 | #import 10 | #import "version.h" 11 | 12 | @interface iPhoneSimulator : NSObject { 13 | @private 14 | DTiPhoneSimulatorSystemRoot *sdkRoot; 15 | NSFileHandle *stdoutFileHandle; 16 | NSFileHandle *stderrFileHandle; 17 | BOOL exit_on_startup; 18 | BOOL verbose; 19 | } 20 | 21 | - (void)runWithArgc:(int)argc argv:(char **)argv; 22 | 23 | - (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path; 24 | - (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Source/nsprintf.m: -------------------------------------------------------------------------------- 1 | /* 2 | * NSLog() clone, but writes to arbitrary output stream 3 | */ 4 | 5 | #import 6 | #import 7 | 8 | int nsvfprintf (FILE *stream, NSString *format, va_list args) { 9 | int retval; 10 | 11 | NSString *str = (NSString *) CFStringCreateWithFormatAndArguments(NULL, NULL, (CFStringRef) format, args); 12 | retval = fprintf(stream, "[DEBUG] %s\n", [str UTF8String]); 13 | [str release]; 14 | 15 | return retval; 16 | } 17 | 18 | int nsfprintf (FILE *stream, NSString *format, ...) { 19 | va_list ap; 20 | int retval; 21 | 22 | va_start(ap, format); 23 | { 24 | retval = nsvfprintf(stream, format, ap); 25 | } 26 | va_end(ap); 27 | 28 | return retval; 29 | } 30 | 31 | int nsprintf (NSString *format, ...) { 32 | va_list ap; 33 | int retval; 34 | 35 | va_start(ap, format); 36 | { 37 | retval = nsvfprintf(stderr, format, ap); 38 | } 39 | va_end(ap); 40 | 41 | return retval; 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ios-sim 2 | ======= 3 | 4 | The ios-sim tool is a command-line utility that launches an iOS application on 5 | the iOS Simulator. This allows for niceties such as automated testing without 6 | having to open XCode. 7 | 8 | Features 9 | -------- 10 | 11 | * Choose the device family to simulate, i.e. iPhone or iPad. 12 | * Setup environment variables. 13 | * Pass arguments to the application. 14 | * See the stdout and stderr, or redirect them to files. 15 | 16 | See the `--help` option for more info. 17 | 18 | Installation 19 | ------------ 20 | 21 | Through homebrew: 22 | 23 | $ brew install ios-sim 24 | 25 | Download an archive: 26 | 27 | $ curl -L https://github.com/Fingertips/ios-sim/zipball/1.1 -o ios-sim-1.1.zip 28 | $ unzip ios-sim-1.1.zip 29 | 30 | Or from a git clone: 31 | 32 | $ git clone git://github.com/Fingertips/ios-sim.git 33 | 34 | Then build and install from the source root: 35 | 36 | $ rake install prefix=/usr/local/bin/ 37 | 38 | License 39 | ------- 40 | 41 | Original author: Landon Fuller 42 | Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc. 43 | All rights reserved. 44 | 45 | This project is available under the MIT license. See [LICENSE][license]. 46 | 47 | [license]: https://github.com/Fingertips/ios-sim/blob/master/LICENSE 48 | -------------------------------------------------------------------------------- /README.template.md: -------------------------------------------------------------------------------- 1 | ios-sim 2 | ======= 3 | 4 | The ios-sim tool is a command-line utility that launches an iOS application on 5 | the iOS Simulator. This allows for niceties such as automated testing without 6 | having to open XCode. 7 | 8 | Features 9 | -------- 10 | 11 | * Choose the device family to simulate, i.e. iPhone or iPad. 12 | * Setup environment variables. 13 | * Pass arguments to the application. 14 | * See the stdout and stderr, or redirect them to files. 15 | 16 | See the `--help` option for more info. 17 | 18 | Installation 19 | ------------ 20 | 21 | Through homebrew: 22 | 23 | $ brew install ios-sim 24 | 25 | Download an archive: 26 | 27 | $ curl -L https://github.com/Fingertips/ios-sim/zipball/{{VERSION}} -o ios-sim-{{VERSION}}.zip 28 | $ unzip ios-sim-{{VERSION}}.zip 29 | 30 | Or from a git clone: 31 | 32 | $ git clone git://github.com/Fingertips/ios-sim.git 33 | 34 | Then build and install from the source root: 35 | 36 | $ rake install prefix=/usr/local/bin/ 37 | 38 | License 39 | ------- 40 | 41 | Original author: Landon Fuller 42 | Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc. 43 | All rights reserved. 44 | 45 | This project is available under the MIT license. See [LICENSE][license]. 46 | 47 | [license]: https://github.com/Fingertips/ios-sim/blob/master/LICENSE 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Author: Landon Fuller 2 | Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc. 3 | All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without 8 | restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following 12 | conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | Modifications made by the following entities are licensed as above: 27 | - Jeff Haynie, Appcelerator, Inc. 28 | - https://github.com/hborders 29 | - http://pivotallabs.com/users/scoward/blog 30 | - Eloy Duran, Fingertips 31 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | def current_version 2 | File.read('Source/version.h').match(/IOS_SIM_VERSION "([\d\.]+)"/)[1] 3 | end 4 | 5 | desc "Create a Release build" 6 | task :build do 7 | sh "xcodebuild -project ios-sim.xcodeproj -configuration Release SYMROOT=build" 8 | end 9 | 10 | desc "Install a Release build" 11 | task :install => :build do 12 | if prefix = ENV['prefix'] 13 | bin_dir = File.join(prefix, 'bin') 14 | mkdir_p bin_dir 15 | cp 'build/Release/ios-sim', bin_dir 16 | else 17 | puts "[!] Specify a directory as the install prefix with the `prefix' env variable" 18 | exit 1 19 | end 20 | end 21 | 22 | desc "Clean" 23 | task :clean do 24 | rm_rf 'build' 25 | end 26 | 27 | desc "Update README.md from README.template.md" 28 | task :readme do 29 | template = File.read('README.template.md') 30 | rendered = template.gsub('{{VERSION}}', current_version) 31 | File.open('README.md', 'w') { |f| f << rendered } 32 | end 33 | 34 | namespace :version do 35 | desc "Print the current version" 36 | task :current do 37 | puts current_version 38 | end 39 | 40 | desc "Bump the version and update the README.md" 41 | task :bump do 42 | if v = ENV['v'] 43 | File.open('Source/version.h', 'w') do |f| 44 | f << %{#define IOS_SIM_VERSION "#{v}"} 45 | end 46 | Rake::Task[:readme].invoke 47 | sh "git commit Source/version.h README.md -m 'Release #{v}'" 48 | sh "git tag -a #{v} -m 'Release #{v}'" 49 | puts "Bumped version to #{current_version}" 50 | else 51 | puts "[!] Specify the version with the `v' env variable" 52 | end 53 | end 54 | end 55 | 56 | desc "Print the current version" 57 | task :version => 'version:current' 58 | 59 | desc "Release a new version" 60 | task :release => 'version:bump' do 61 | sh "git push" 62 | sh "git push --tags" 63 | end 64 | -------------------------------------------------------------------------------- /iPhoneSimulatorRemoteClient/iPhoneSimulatorRemoteClient.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | /* 4 | * File: /Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/iPhoneSimulatorRemoteClient.framework/Versions/A/iPhoneSimulatorRemoteClient 5 | * Arch: Intel 80x86 (i386) 6 | * Current version: 12.0.0, Compatibility version: 1.0.0 7 | */ 8 | 9 | @class DTiPhoneSimulatorSession; 10 | 11 | @protocol DTiPhoneSimulatorSessionDelegate 12 | 13 | - (void) session: (DTiPhoneSimulatorSession *) session didEndWithError: (NSError *) error; 14 | - (void) session: (DTiPhoneSimulatorSession *) session didStart: (BOOL) started withError: (NSError *) error; 15 | 16 | @end 17 | 18 | @interface DTiPhoneSimulatorApplicationSpecifier : NSObject 19 | { 20 | NSString *_appPath; 21 | NSString *_bundleID; 22 | } 23 | 24 | + (id) specifierWithApplicationPath: (NSString *) appPath; 25 | + (id) specifierWithApplicationBundleIdentifier: (NSString *) bundleID; 26 | - (NSString *) bundleID; 27 | - (void) setBundleID: (NSString *) bundleId; 28 | - (NSString *) appPath; 29 | - (void) setAppPath: (NSString *) appPath; 30 | 31 | @end 32 | 33 | @interface DTiPhoneSimulatorSystemRoot : NSObject 34 | { 35 | NSString *sdkRootPath; 36 | NSString *sdkVersion; 37 | NSString *sdkDisplayName; 38 | } 39 | 40 | + (id) defaultRoot; 41 | 42 | + (id)rootWithSDKPath:(id)fp8; 43 | + (id)rootWithSDKVersion:(id)fp8; 44 | + (NSArray *) knownRoots; 45 | - (id)initWithSDKPath:(id)fp8; 46 | - (id)sdkDisplayName; 47 | - (void)setSdkDisplayName:(id)fp8; 48 | - (id)sdkVersion; 49 | - (void)setSdkVersion:(id)fp8; 50 | - (id)sdkRootPath; 51 | - (void)setSdkRootPath:(id)fp8; 52 | 53 | @end 54 | 55 | 56 | 57 | @interface DTiPhoneSimulatorSessionConfig : NSObject 58 | { 59 | NSString *_localizedClientName; 60 | DTiPhoneSimulatorSystemRoot *_simulatedSystemRoot; 61 | DTiPhoneSimulatorApplicationSpecifier *_applicationToSimulateOnStart; 62 | NSArray *_simulatedApplicationLaunchArgs; 63 | NSDictionary *_simulatedApplicationLaunchEnvironment; 64 | BOOL _simulatedApplicationShouldWaitForDebugger; 65 | NSString *_simulatedApplicationStdOutPath; 66 | NSString *_simulatedApplicationStdErrPath; 67 | } 68 | 69 | - (id)simulatedApplicationStdErrPath; 70 | - (void)setSimulatedApplicationStdErrPath:(id)fp8; 71 | - (id)simulatedApplicationStdOutPath; 72 | - (void)setSimulatedApplicationStdOutPath:(id)fp8; 73 | - (id)simulatedApplicationLaunchEnvironment; 74 | - (void)setSimulatedApplicationLaunchEnvironment:(id)fp8; 75 | - (id)simulatedApplicationLaunchArgs; 76 | - (void)setSimulatedApplicationLaunchArgs:(id)fp8; 77 | 78 | - (DTiPhoneSimulatorApplicationSpecifier *) applicationToSimulateOnStart; 79 | - (void) setApplicationToSimulateOnStart: (DTiPhoneSimulatorApplicationSpecifier *) appSpec; 80 | - (DTiPhoneSimulatorSystemRoot *) simulatedSystemRoot; 81 | - (void) setSimulatedSystemRoot: (DTiPhoneSimulatorSystemRoot *) simulatedSystemRoot; 82 | 83 | 84 | - (BOOL) simulatedApplicationShouldWaitForDebugger; 85 | - (void) setSimulatedApplicationShouldWaitForDebugger: (BOOL) waitForDebugger; 86 | 87 | - (id)localizedClientName; 88 | - (void)setLocalizedClientName:(id)fp8; 89 | 90 | // Added in 3.2 to support iPad/iPhone device families 91 | - (void)setSimulatedDeviceFamily:(NSNumber*)family; 92 | 93 | @end 94 | 95 | 96 | @interface DTiPhoneSimulatorSession : NSObject { 97 | NSString *_uuid; 98 | id _delegate; 99 | NSNumber *_simulatedApplicationPID; 100 | int _sessionLifecycleProgress; 101 | NSTimer *_timeoutTimer; 102 | DTiPhoneSimulatorSessionConfig *_sessionConfig; 103 | struct ProcessSerialNumber _simulatorPSN; 104 | } 105 | 106 | - (BOOL) requestStartWithConfig: (DTiPhoneSimulatorSessionConfig *) config timeout: (NSTimeInterval) timeout error: (NSError **) outError; 107 | - (void) requestEndWithTimeout: (NSTimeInterval) timeout; 108 | 109 | - (id)sessionConfig; 110 | - (void)setSessionConfig:(id)fp8; 111 | - (id)timeoutTimer; 112 | - (void)setTimeoutTimer:(id)fp8; 113 | - (int)sessionLifecycleProgress; 114 | - (void)setSessionLifecycleProgress:(int)fp8; 115 | - (id)simulatedApplicationPID; 116 | - (void)setSimulatedApplicationPID:(id)fp8; 117 | 118 | - (id) delegate; 119 | - (void) setDelegate: (id) delegate; 120 | 121 | - (id)uuid; 122 | - (void)setUuid:(id)fp8; 123 | 124 | @end 125 | -------------------------------------------------------------------------------- /ios-sim.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2481364C115A750000E3A9BA /* iPhoneSimulator.m in Sources */ = {isa = PBXBuildFile; fileRef = 24813648115A750000E3A9BA /* iPhoneSimulator.m */; }; 11 | 2481364D115A750000E3A9BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 24813649115A750000E3A9BA /* main.m */; }; 12 | 2481364E115A750000E3A9BA /* nsprintf.m in Sources */ = {isa = PBXBuildFile; fileRef = 2481364B115A750000E3A9BA /* nsprintf.m */; }; 13 | 51448B3412BCF637001F99BD /* NSString+expandPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 51448B3312BCF637001F99BD /* NSString+expandPath.m */; }; 14 | 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXCopyFilesBuildPhase section */ 18 | 8DD76F9E0486AA7600D96B5E /* CopyFiles */ = { 19 | isa = PBXCopyFilesBuildPhase; 20 | buildActionMask = 8; 21 | dstPath = /usr/share/man/man1/; 22 | dstSubfolderSpec = 0; 23 | files = ( 24 | ); 25 | runOnlyForDeploymentPostprocessing = 1; 26 | }; 27 | /* End PBXCopyFilesBuildPhase section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 31 | 24813647115A750000E3A9BA /* iPhoneSimulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iPhoneSimulator.h; path = Source/iPhoneSimulator.h; sourceTree = ""; }; 32 | 24813648115A750000E3A9BA /* iPhoneSimulator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iPhoneSimulator.m; path = Source/iPhoneSimulator.m; sourceTree = ""; }; 33 | 24813649115A750000E3A9BA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Source/main.m; sourceTree = ""; }; 34 | 2481364A115A750000E3A9BA /* nsprintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = nsprintf.h; path = Source/nsprintf.h; sourceTree = ""; }; 35 | 2481364B115A750000E3A9BA /* nsprintf.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = nsprintf.m; path = Source/nsprintf.m; sourceTree = ""; }; 36 | 32A70AAB03705E1F00C91783 /* ios-sim_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ios-sim_Prefix.pch"; sourceTree = ""; }; 37 | 51448B3212BCF637001F99BD /* NSString+expandPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSString+expandPath.h"; path = "Source/NSString+expandPath.h"; sourceTree = ""; }; 38 | 51448B3312BCF637001F99BD /* NSString+expandPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+expandPath.m"; path = "Source/NSString+expandPath.m"; sourceTree = ""; }; 39 | 51448B3512BD0328001F99BD /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = version.h; path = Source/version.h; sourceTree = ""; }; 40 | 8DD76FA10486AA7600D96B5E /* ios-sim */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "ios-sim"; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 8DD76F9B0486AA7600D96B5E /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | 08FB7794FE84155DC02AAC07 /* iphonesim */ = { 56 | isa = PBXGroup; 57 | children = ( 58 | 08FB7795FE84155DC02AAC07 /* Source */, 59 | 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, 60 | 1AB674ADFE9D54B511CA2CBB /* Products */, 61 | ); 62 | name = iphonesim; 63 | sourceTree = ""; 64 | }; 65 | 08FB7795FE84155DC02AAC07 /* Source */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 24813647115A750000E3A9BA /* iPhoneSimulator.h */, 69 | 24813648115A750000E3A9BA /* iPhoneSimulator.m */, 70 | 24813649115A750000E3A9BA /* main.m */, 71 | 2481364A115A750000E3A9BA /* nsprintf.h */, 72 | 2481364B115A750000E3A9BA /* nsprintf.m */, 73 | 32A70AAB03705E1F00C91783 /* ios-sim_Prefix.pch */, 74 | 51448B3212BCF637001F99BD /* NSString+expandPath.h */, 75 | 51448B3312BCF637001F99BD /* NSString+expandPath.m */, 76 | 51448B3512BD0328001F99BD /* version.h */, 77 | ); 78 | name = Source; 79 | sourceTree = ""; 80 | }; 81 | 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 08FB779EFE84155DC02AAC07 /* Foundation.framework */, 85 | ); 86 | name = "External Frameworks and Libraries"; 87 | sourceTree = ""; 88 | }; 89 | 1AB674ADFE9D54B511CA2CBB /* Products */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 8DD76FA10486AA7600D96B5E /* ios-sim */, 93 | ); 94 | name = Products; 95 | sourceTree = ""; 96 | }; 97 | /* End PBXGroup section */ 98 | 99 | /* Begin PBXNativeTarget section */ 100 | 8DD76F960486AA7600D96B5E /* ios-sim */ = { 101 | isa = PBXNativeTarget; 102 | buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "ios-sim" */; 103 | buildPhases = ( 104 | 8DD76F990486AA7600D96B5E /* Sources */, 105 | 8DD76F9B0486AA7600D96B5E /* Frameworks */, 106 | 8DD76F9E0486AA7600D96B5E /* CopyFiles */, 107 | ); 108 | buildRules = ( 109 | ); 110 | dependencies = ( 111 | ); 112 | name = "ios-sim"; 113 | productInstallPath = "$(HOME)/bin"; 114 | productName = iphonesim; 115 | productReference = 8DD76FA10486AA7600D96B5E /* ios-sim */; 116 | productType = "com.apple.product-type.tool"; 117 | }; 118 | /* End PBXNativeTarget section */ 119 | 120 | /* Begin PBXProject section */ 121 | 08FB7793FE84155DC02AAC07 /* Project object */ = { 122 | isa = PBXProject; 123 | buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "ios-sim" */; 124 | compatibilityVersion = "Xcode 3.1"; 125 | developmentRegion = English; 126 | hasScannedForEncodings = 1; 127 | knownRegions = ( 128 | English, 129 | Japanese, 130 | French, 131 | German, 132 | ); 133 | mainGroup = 08FB7794FE84155DC02AAC07 /* iphonesim */; 134 | projectDirPath = ""; 135 | projectRoot = ""; 136 | targets = ( 137 | 8DD76F960486AA7600D96B5E /* ios-sim */, 138 | ); 139 | }; 140 | /* End PBXProject section */ 141 | 142 | /* Begin PBXSourcesBuildPhase section */ 143 | 8DD76F990486AA7600D96B5E /* Sources */ = { 144 | isa = PBXSourcesBuildPhase; 145 | buildActionMask = 2147483647; 146 | files = ( 147 | 2481364C115A750000E3A9BA /* iPhoneSimulator.m in Sources */, 148 | 2481364D115A750000E3A9BA /* main.m in Sources */, 149 | 2481364E115A750000E3A9BA /* nsprintf.m in Sources */, 150 | 51448B3412BCF637001F99BD /* NSString+expandPath.m in Sources */, 151 | ); 152 | runOnlyForDeploymentPostprocessing = 0; 153 | }; 154 | /* End PBXSourcesBuildPhase section */ 155 | 156 | /* Begin XCBuildConfiguration section */ 157 | 1DEB927508733DD40010E9CD /* Debug */ = { 158 | isa = XCBuildConfiguration; 159 | buildSettings = { 160 | ALWAYS_SEARCH_USER_PATHS = NO; 161 | COPY_PHASE_STRIP = NO; 162 | FRAMEWORK_SEARCH_PATHS = ( 163 | "$(inherited)", 164 | "\"$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks\"", 165 | ); 166 | GCC_DYNAMIC_NO_PIC = NO; 167 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 168 | GCC_MODEL_TUNING = G5; 169 | GCC_OPTIMIZATION_LEVEL = 0; 170 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 171 | GCC_PREFIX_HEADER = "ios-sim_Prefix.pch"; 172 | INSTALL_PATH = /usr/local/bin; 173 | PRODUCT_NAME = "ios-sim"; 174 | }; 175 | name = Debug; 176 | }; 177 | 1DEB927608733DD40010E9CD /* Release */ = { 178 | isa = XCBuildConfiguration; 179 | buildSettings = { 180 | ALWAYS_SEARCH_USER_PATHS = NO; 181 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 182 | FRAMEWORK_SEARCH_PATHS = ( 183 | "$(inherited)", 184 | "\"$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks\"", 185 | ); 186 | GCC_MODEL_TUNING = G5; 187 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 188 | GCC_PREFIX_HEADER = "ios-sim_Prefix.pch"; 189 | INSTALL_PATH = /usr/local/bin; 190 | PRODUCT_NAME = "ios-sim"; 191 | }; 192 | name = Release; 193 | }; 194 | 1DEB927908733DD40010E9CD /* Debug */ = { 195 | isa = XCBuildConfiguration; 196 | buildSettings = { 197 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 198 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks"; 199 | GCC_C_LANGUAGE_STANDARD = gnu99; 200 | GCC_OPTIMIZATION_LEVEL = 0; 201 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 202 | GCC_WARN_UNUSED_VARIABLE = YES; 203 | HEADER_SEARCH_PATHS = .; 204 | ONLY_ACTIVE_ARCH = NO; 205 | OTHER_LDFLAGS = ( 206 | "-framework", 207 | AppKit, 208 | "-F$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks", 209 | "-framework", 210 | iPhoneSimulatorRemoteClient, 211 | "-Wl,-rpath", 212 | "-Wl,$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks", 213 | ); 214 | PREBINDING = NO; 215 | SDKROOT = macosx10.6; 216 | VALID_ARCHS = "i386 x86_64"; 217 | }; 218 | name = Debug; 219 | }; 220 | 1DEB927A08733DD40010E9CD /* Release */ = { 221 | isa = XCBuildConfiguration; 222 | buildSettings = { 223 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 224 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks"; 225 | GCC_C_LANGUAGE_STANDARD = gnu99; 226 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 227 | GCC_WARN_UNUSED_VARIABLE = YES; 228 | HEADER_SEARCH_PATHS = .; 229 | ONLY_ACTIVE_ARCH = NO; 230 | OTHER_LDFLAGS = ( 231 | "-framework", 232 | AppKit, 233 | "-F$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks", 234 | "-framework", 235 | iPhoneSimulatorRemoteClient, 236 | "-Wl,-rpath", 237 | "-Wl,$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks", 238 | ); 239 | PREBINDING = NO; 240 | SDKROOT = macosx10.6; 241 | VALID_ARCHS = "i386 x86_64"; 242 | }; 243 | name = Release; 244 | }; 245 | /* End XCBuildConfiguration section */ 246 | 247 | /* Begin XCConfigurationList section */ 248 | 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "ios-sim" */ = { 249 | isa = XCConfigurationList; 250 | buildConfigurations = ( 251 | 1DEB927508733DD40010E9CD /* Debug */, 252 | 1DEB927608733DD40010E9CD /* Release */, 253 | ); 254 | defaultConfigurationIsVisible = 0; 255 | defaultConfigurationName = Release; 256 | }; 257 | 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "ios-sim" */ = { 258 | isa = XCConfigurationList; 259 | buildConfigurations = ( 260 | 1DEB927908733DD40010E9CD /* Debug */, 261 | 1DEB927A08733DD40010E9CD /* Release */, 262 | ); 263 | defaultConfigurationIsVisible = 0; 264 | defaultConfigurationName = Release; 265 | }; 266 | /* End XCConfigurationList section */ 267 | }; 268 | rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; 269 | } 270 | -------------------------------------------------------------------------------- /Source/iPhoneSimulator.m: -------------------------------------------------------------------------------- 1 | /* Author: Landon Fuller 2 | * Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc. 3 | * All rights reserved. 4 | * 5 | * See the LICENSE file for the license on the source code in this file. 6 | */ 7 | 8 | #import "iPhoneSimulator.h" 9 | #import "NSString+expandPath.h" 10 | #import "nsprintf.h" 11 | #import 12 | #import 13 | 14 | /** 15 | * A simple iPhoneSimulatorRemoteClient framework. 16 | */ 17 | @implementation iPhoneSimulator 18 | 19 | - (void) printUsage { 20 | fprintf(stderr, "Usage: ios-sim [--args ...]\n"); 21 | fprintf(stderr, "\n"); 22 | fprintf(stderr, "Commands:\n"); 23 | fprintf(stderr, " showsdks List the available iOS SDK versions\n"); 24 | fprintf(stderr, " launch Launch the application at the specified path on the iOS Simulator\n"); 25 | fprintf(stderr, "\n"); 26 | fprintf(stderr, "Options:\n"); 27 | fprintf(stderr, " --version Print the version of ios-sim\n"); 28 | fprintf(stderr, " --help Show this help text\n"); 29 | fprintf(stderr, " --verbose Set the output level to verbose\n"); 30 | fprintf(stderr, " --exit Exit after startup\n"); 31 | fprintf(stderr, " --sdk The iOS SDK version to run the application on (defaults to the latest)\n"); 32 | fprintf(stderr, " --family The device type that should be simulated (defaults to `iphone')\n"); 33 | fprintf(stderr, " --uuid A UUID identifying the session (is that correct?)\n"); 34 | fprintf(stderr, " --env A plist file containing environment key-value pairs that should be set\n"); 35 | fprintf(stderr, " --setenv NAME=VALUE Set an environment variable\n"); 36 | fprintf(stderr, " --stdout The path where stdout of the simulator will be redirected to (defaults to stdout of iphonesim)\n"); 37 | fprintf(stderr, " --stderr The path where stderr of the simulator will be redirected to (defaults to stderr of iphonesim)\n"); 38 | fprintf(stderr, " --args <...> All following arguments will be passed on to the application\n"); 39 | } 40 | 41 | 42 | - (int) showSDKs { 43 | NSArray *roots = [DTiPhoneSimulatorSystemRoot knownRoots]; 44 | 45 | nsprintf(@"Simulator SDK Roots:"); 46 | for (DTiPhoneSimulatorSystemRoot *root in roots) { 47 | nsfprintf(stderr, @"'%@' (%@)\n\t%@", [root sdkDisplayName], [root sdkVersion], [root sdkRootPath]); 48 | } 49 | 50 | return EXIT_SUCCESS; 51 | } 52 | 53 | 54 | - (void)session:(DTiPhoneSimulatorSession *)session didEndWithError:(NSError *)error { 55 | if (verbose) { 56 | nsprintf(@"Session did end with error %@", error); 57 | } 58 | 59 | if (stderrFileHandle != nil) { 60 | NSString *stderrPath = [[session sessionConfig] simulatedApplicationStdErrPath]; 61 | [self removeStdioFIFO:stderrFileHandle atPath:stderrPath]; 62 | } 63 | 64 | if (stdoutFileHandle != nil) { 65 | NSString *stdoutPath = [[session sessionConfig] simulatedApplicationStdOutPath]; 66 | [self removeStdioFIFO:stdoutFileHandle atPath:stdoutPath]; 67 | } 68 | 69 | if (error != nil) { 70 | exit(EXIT_FAILURE); 71 | } 72 | 73 | exit(EXIT_SUCCESS); 74 | } 75 | 76 | 77 | - (void)session:(DTiPhoneSimulatorSession *)session didStart:(BOOL)started withError:(NSError *)error { 78 | if (started) { 79 | if (verbose) { 80 | nsprintf(@"Session started"); 81 | } 82 | if (exit_on_startup) { 83 | exit(EXIT_SUCCESS); 84 | } 85 | } else { 86 | nsprintf(@"Session could not be started: %@", error); 87 | exit(EXIT_FAILURE); 88 | } 89 | } 90 | 91 | 92 | - (void)stdioDataIsAvailable:(NSNotification *)notification { 93 | NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem]; 94 | NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 95 | if ([notification object] == stdoutFileHandle) { 96 | printf("%s", [str UTF8String]); 97 | } else { 98 | nsprintf(str); 99 | } 100 | } 101 | 102 | 103 | - (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path { 104 | *path = [NSString stringWithFormat:@"/tmp/iphonesim-%@-pipe-%d", type, (int)time(NULL)]; 105 | if (mkfifo([*path UTF8String], S_IRUSR | S_IWUSR) == -1) { 106 | nsprintf(@"Unable to create %@ named pipe `%@'", type, *path); 107 | exit(EXIT_FAILURE); 108 | } else { 109 | if (verbose) { 110 | nsprintf(@"Creating named pipe at `%@'", *path); 111 | } 112 | int fd = open([*path UTF8String], O_RDONLY | O_NDELAY); 113 | *fileHandle = [[[NSFileHandle alloc] initWithFileDescriptor:fd] retain]; 114 | [*fileHandle readInBackgroundAndNotify]; 115 | [[NSNotificationCenter defaultCenter] addObserver:self 116 | selector:@selector(stdioDataIsAvailable:) 117 | name:NSFileHandleReadCompletionNotification 118 | object:*fileHandle]; 119 | } 120 | } 121 | 122 | 123 | - (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path { 124 | if (verbose) { 125 | nsprintf(@"Removing named pipe at `%@'", path); 126 | } 127 | [fileHandle closeFile]; 128 | [fileHandle release]; 129 | if (![[NSFileManager defaultManager] removeItemAtPath:path error:NULL]) { 130 | nsprintf(@"Unable to remove named pipe `%@'", path); 131 | } 132 | } 133 | 134 | 135 | - (int)launchApp:(NSString *)path withFamily:(NSString *)family 136 | uuid:(NSString *)uuid 137 | environment:(NSDictionary *)environment 138 | stdoutPath:(NSString *)stdoutPath 139 | stderrPath:(NSString *)stderrPath 140 | args:(NSArray *)args { 141 | DTiPhoneSimulatorApplicationSpecifier *appSpec; 142 | DTiPhoneSimulatorSessionConfig *config; 143 | DTiPhoneSimulatorSession *session; 144 | NSError *error; 145 | 146 | /* Create the app specifier */ 147 | appSpec = [DTiPhoneSimulatorApplicationSpecifier specifierWithApplicationPath:path]; 148 | if (appSpec == nil) { 149 | nsprintf(@"Could not load application specification for %s", path); 150 | return EXIT_FAILURE; 151 | } 152 | if (verbose) { 153 | nsprintf(@"App Spec: %@", appSpec); 154 | nsprintf(@"SDK Root: %@", sdkRoot); 155 | 156 | for (id key in environment) { 157 | nsprintf(@"Env: %@ = %@", key, [environment objectForKey:key]); 158 | } 159 | } 160 | 161 | /* Set up the session configuration */ 162 | config = [[[DTiPhoneSimulatorSessionConfig alloc] init] autorelease]; 163 | [config setApplicationToSimulateOnStart:appSpec]; 164 | [config setSimulatedSystemRoot:sdkRoot]; 165 | [config setSimulatedApplicationShouldWaitForDebugger: NO]; 166 | 167 | [config setSimulatedApplicationLaunchArgs:args]; 168 | [config setSimulatedApplicationLaunchEnvironment:environment]; 169 | 170 | if (stderrPath) { 171 | stderrFileHandle = nil; 172 | } else if (!exit_on_startup) { 173 | [self createStdioFIFO:&stderrFileHandle ofType:@"stderr" atPath:&stderrPath]; 174 | } 175 | [config setSimulatedApplicationStdErrPath:stderrPath]; 176 | 177 | if (stdoutPath) { 178 | stdoutFileHandle = nil; 179 | } else if (!exit_on_startup) { 180 | [self createStdioFIFO:&stdoutFileHandle ofType:@"stdout" atPath:&stdoutPath]; 181 | } 182 | [config setSimulatedApplicationStdOutPath:stdoutPath]; 183 | 184 | [config setLocalizedClientName: @"iphonesim"]; 185 | 186 | // this was introduced in 3.2 of SDK 187 | if ([config respondsToSelector:@selector(setSimulatedDeviceFamily:)]) { 188 | if (family == nil) { 189 | family = @"iphone"; 190 | } 191 | 192 | if (verbose) { 193 | nsprintf(@"using device family %@",family); 194 | } 195 | 196 | if ([family isEqualToString:@"ipad"]) { 197 | [config setSimulatedDeviceFamily:[NSNumber numberWithInt:2]]; 198 | } else{ 199 | [config setSimulatedDeviceFamily:[NSNumber numberWithInt:1]]; 200 | } 201 | } 202 | 203 | /* Start the session */ 204 | session = [[[DTiPhoneSimulatorSession alloc] init] autorelease]; 205 | [session setDelegate:self]; 206 | [session setSimulatedApplicationPID: [NSNumber numberWithInt:35]]; 207 | if (uuid != nil){ 208 | [session setUuid:uuid]; 209 | } 210 | 211 | if (![session requestStartWithConfig:config timeout:30 error:&error]) { 212 | nsprintf(@"Could not start simulator session: %@", error); 213 | return EXIT_FAILURE; 214 | } 215 | 216 | return EXIT_SUCCESS; 217 | } 218 | 219 | 220 | /** 221 | * Execute 'main' 222 | */ 223 | - (void)runWithArgc:(int)argc argv:(char **)argv { 224 | if (argc < 2) { 225 | [self printUsage]; 226 | exit(EXIT_FAILURE); 227 | } 228 | 229 | if (strcmp(argv[1], "showsdks") == 0) { 230 | exit([self showSDKs]); 231 | } else if (strcmp(argv[1], "launch") == 0) { 232 | if (argc < 3) { 233 | fprintf(stderr, "Missing application path argument\n"); 234 | [self printUsage]; 235 | exit(EXIT_FAILURE); 236 | } 237 | 238 | NSString *appPath = [[NSString stringWithUTF8String:argv[2]] expandPath]; 239 | NSString *family = nil; 240 | NSString *uuid = nil; 241 | NSString *stdoutPath = nil; 242 | NSString *stderrPath = nil; 243 | NSMutableDictionary *environment = [NSMutableDictionary dictionary]; 244 | int i = 3; 245 | for (; i < argc; i++) { 246 | if (strcmp(argv[i], "--version") == 0) { 247 | printf("%s\n", IOS_SIM_VERSION); 248 | exit(EXIT_SUCCESS); 249 | } else if (strcmp(argv[i], "--help") == 0) { 250 | [self printUsage]; 251 | exit(EXIT_SUCCESS); 252 | } else if (strcmp(argv[i], "--verbose") == 0) { 253 | verbose = YES; 254 | } else if (strcmp(argv[i], "--exit") == 0) { 255 | exit_on_startup = YES; 256 | } 257 | else if (strcmp(argv[i], "--sdk") == 0) { 258 | i++; 259 | NSString* ver = [NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding]; 260 | NSArray *roots = [DTiPhoneSimulatorSystemRoot knownRoots]; 261 | for (DTiPhoneSimulatorSystemRoot *root in roots) { 262 | NSString *v = [root sdkVersion]; 263 | if ([v isEqualToString:ver]) { 264 | sdkRoot = root; 265 | break; 266 | } 267 | } 268 | if (sdkRoot == nil) { 269 | fprintf(stderr,"Unknown or unsupported SDK version: %s\n",argv[i]); 270 | [self showSDKs]; 271 | exit(EXIT_FAILURE); 272 | } 273 | } else if (strcmp(argv[i], "--family") == 0) { 274 | i++; 275 | family = [NSString stringWithUTF8String:argv[i]]; 276 | } else if (strcmp(argv[i], "--uuid") == 0) { 277 | i++; 278 | uuid = [NSString stringWithUTF8String:argv[i]]; 279 | } else if (strcmp(argv[i], "--setenv") == 0) { 280 | i++; 281 | NSArray *parts = [[NSString stringWithUTF8String:argv[i]] componentsSeparatedByString:@"="]; 282 | [environment setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]]; 283 | } else if (strcmp(argv[i], "--env") == 0) { 284 | i++; 285 | NSString *envFilePath = [[NSString stringWithUTF8String:argv[i]] expandPath]; 286 | environment = [NSDictionary dictionaryWithContentsOfFile:envFilePath]; 287 | if (!environment) { 288 | fprintf(stderr, "Could not read environment from file: %s\n", argv[i]); 289 | [self printUsage]; 290 | exit(EXIT_FAILURE); 291 | } 292 | } else if (strcmp(argv[i], "--stdout") == 0) { 293 | i++; 294 | stdoutPath = [[NSString stringWithUTF8String:argv[i]] expandPath]; 295 | NSLog(@"stdoutPath: %@", stdoutPath); 296 | } else if (strcmp(argv[i], "--stderr") == 0) { 297 | i++; 298 | stderrPath = [[NSString stringWithUTF8String:argv[i]] expandPath]; 299 | NSLog(@"stderrPath: %@", stderrPath); 300 | } else if (strcmp(argv[i], "--args") == 0) { 301 | i++; 302 | break; 303 | } else { 304 | fprintf(stderr, "unrecognized argument:%s\n", argv[i]); 305 | [self printUsage]; 306 | exit(EXIT_FAILURE); 307 | } 308 | } 309 | NSMutableArray *args = [NSMutableArray arrayWithCapacity:(argc - i)]; 310 | for (; i < argc; i++) { 311 | [args addObject:[NSString stringWithUTF8String:argv[i]]]; 312 | } 313 | 314 | if (sdkRoot == nil) { 315 | sdkRoot = [DTiPhoneSimulatorSystemRoot defaultRoot]; 316 | } 317 | 318 | /* Don't exit, adds to runloop */ 319 | [self launchApp:appPath 320 | withFamily:family 321 | uuid:uuid 322 | environment:environment 323 | stdoutPath:stdoutPath 324 | stderrPath:stderrPath 325 | args:args]; 326 | } else { 327 | if (argc == 2 && strcmp(argv[1], "--help") == 0) { 328 | [self printUsage]; 329 | exit(EXIT_SUCCESS); 330 | } else if (argc == 2 && strcmp(argv[1], "--version") == 0) { 331 | printf("%s\n", IOS_SIM_VERSION); 332 | exit(EXIT_SUCCESS); 333 | } else { 334 | fprintf(stderr, "Unknown command\n"); 335 | [self printUsage]; 336 | exit(EXIT_FAILURE); 337 | } 338 | } 339 | } 340 | 341 | @end 342 | --------------------------------------------------------------------------------