Search code examples
iosobjective-ccoderunner

How to compile SecureUDID with CodeRunner


I'm trying to quickly test what kind of results I'd get using SecureUDID before I can use in my Xcode project. In this case I'm using CodeRunner but I've never compiled obj-c code outside of Xcode. I've attached the error I'm getting when using the default compilation flag CodeRunner provides for Obj-c files. I've experimented with compilation flag options inspired from the answer for this questions but still getting essentially the same error. What compilation flags should I be using? Are there any good resources to learn how to compile obj-c outside of Xcode? Please help thanks!

enter image description here

Update: It looks like I need to add UIKit and maybe others to the compilation flags now?

enter image description here


Solution

  • I agree with Mattia, Xcode is probably the best way to go, however: CHALLENGE ACCEPTED.


    First, let's get CodeRunner to compile with UIKit. In the CodeRunner preferences, duplicate the Objective-C language and name it something like "iOS". I'm using the command that Xcode uses (which you can find in the Log Navigator) as a template. This is also what Mattia was talking about. Set the Compilation Flags to something like this:

    -arch i386 -fmessage-length=0 -std=c99 -fpascal-strings -O0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk -fexceptions -fasm-blocks -g -fvisibility=hidden -fobjc-abi-version=2 -fobjc-legacy-dispatch -mios-simulator-version-min=5.1 -framework Foundation -framework UIKit -F /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk/System/Library/Frameworks

    Note the iPhoneSimulator5.1.sdk path and -mios-simulator-version-min=5.1 flag. You may need to change these for your own system and versions.

    To start, try using the following iOS code (you can also make this your template in the preferences):

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    @interface AppDelegate : NSObject <UIApplicationDelegate>
    
    @property (nonatomic, retain) UIWindow * window;
    @property (nonatomic, retain) UIViewController * viewController;
    
    @end
    
    @implementation AppDelegate
    
    @synthesize window = _window;
    @synthesize viewController = _viewController;
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        self.viewController = [[[UIViewController alloc] initWithNibName:nil bundle:nil] autorelease];
        self.viewController.view.backgroundColor = [UIColor orangeColor];
        UILabel * label = [[UILabel alloc] initWithFrame:self.viewController.view.bounds];
        label.font = [UIFont boldSystemFontOfSize:48.0];
        label.textColor = [UIColor whiteColor];
        label.backgroundColor = [UIColor clearColor];
        label.textAlignment = UITextAlignmentCenter;
        label.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        label.text = @"Hello World";
        [self.viewController.view addSubview:label];
        [label release];
    
        self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
        self.window.rootViewController = self.viewController;
        [self.window makeKeyAndVisible];
    
        return YES;
    }
    
    @end
    
    int main(int argc, char *argv[]) {
        @autoreleasepool {
            UIApplicationMain(argc, argv, nil, @"AppDelegate");
        }
    }
    

    If you try to run, it should compile, however the application will crash with this error:

    dyld: Library not loaded: /System/Library/Frameworks/UIKit.framework/UIKit

    This is because you're trying to run an iOS app on a Mac, which doesn't have UIKit available; it needs to run in the simulator. Back in the preferences, change Run Command to:

    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone\ Simulator.app/Contents/MacOS/iPhone\ Simulator -SimulateApplication $PWD/$compiler

    Now run the same code. The iOS Simulator should launch and you should see an orange screen with "Hello World":

    Hello World

    Now to get it to work with SecureUDID. You'll need to save the code somewhere. Now copy the SecureUDID .h and .m files into the same folder as the saved code. Add #import "SecureUDID.h" to the top of the file, change the font size to 14.0, and change @"Hello World" to [SecureUDID UDIDForDomain:@"com.example.test" usingKey:@"abcdefg"]. If you run the code, it will complain that it can't find the SecureUDID symbols, as you were seeing. We'll need to add "SecureUDID.m" to the Compilation Flags. So you can reuse the iOS language in CodeRunner, you can add this to the flags in Custom Run, however you'll need to deal with that modal view each time you want to run.

    And there you go:

    SecureUDID

    Unfortunately, logging will not appear in the CodeRunner console, but you can open up the Mac app, Console, to see them. I'm also getting some extra black padding. Not yet sure what I'm doing wrong to get that.