Skip to content

Instantly share code, notes, and snippets.

@squishykid
Forked from elliottsj/uikit-apple-watch.md
Last active February 13, 2024 23:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save squishykid/5259e6bb98e563c8161a to your computer and use it in GitHub Desktop.
Save squishykid/5259e6bb98e563c8161a to your computer and use it in GitHub Desktop.
My attempt at getting UIKit to work on watchOS 2

Update: UIKit works!! More complete post & info incoming, after http://hackthenorth.com/ (where I am now) is over.

img_0016


Attempting to get React Native to work on watchOS 2, starting with trying to get just UIKit working like @steventroughtonsmith: http://blog.steventroughtonsmith.com/post/128957959685/native-uikit-apps-on-apple-watch

The 'ActualWatchApp' framework target is linked to React Native headers via Cocoapods; currently just trying to get the 'PlainWatchApp' framework target (which isn't linked to React Native) working.

screenshot 2015-09-19 23 14 04

Targets

VanillaWatch

iPhone app

VanillaWatch WatchKit App

Watch app

VanillaWatch WatchKit Extension

ActualWatchApp

Watch Framework (linked with React Native via cocoapods)

PlainWatchApp

Watch Framework

// PlainWatchApp/main.m

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

void __attribute__((constructor)) injected_main()
{
    @autoreleasepool {
        UIApplicationMain(0, nil, @"UIApplication", NSStringFromClass([AppDelegate class]));
    }
}
// PlainWatchApp/AppDelegate.h

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end
// PlainWatchApp/AppDelegate.m

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    /*
     * Just drawing a blue rect; works on iPhone
     */
    UIScreen *mainScreen = [UIScreen mainScreen];
    CGRect bounds = mainScreen.bounds;
    self.window = [[UIWindow alloc] initWithFrame:bounds];
    UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
    aView.backgroundColor = [UIColor blueColor];
    UIViewController *rootViewController = [[UIViewController alloc] init];
    rootViewController.view = aView;
    self.window.rootViewController = rootViewController;
    [self.window makeKeyAndVisible];
    return YES;
}

@end

Copy Frameworks from iPhoneOS.platform to WatchOS.platform

Copied all required frameworks from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/ to /Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk/System/Library/Frameworks/ and added armv7k to .tbd files.

Attempt at copying dylib & signing

# Copy dylib
cp PlainWatchApp.framework/PlainWatchApp VanillaWatch\ WatchKit\ App.app/Frameworks/PlainWatchApp.dylib
# Change LC_LOAD_DYLIB path for iPhoneOS.platform
PLATFORMSDIR=`xcode-select -p`/Platforms \
install_name_tool -change \
/System/Library/PrivateFrameworks/SockPuppetGizmo.framework/SockPuppetGizmo \
@rpath/PlainWatchApp.dylib \
$PLATFORMSDIR/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/Library/Application\ Support/WatchKit/WK
# Change LC_LOAD_DYLIB path for VanillaWatch WatchKit App.app
PRODUCTSDIR=~/Library/Developer/Xcode/DerivedData/VanillaWatch-aswcmlzpigpgdafnukwlclhyohvl/Build/Products/Debug-watchos \
install_name_tool -change \
/System/Library/PrivateFrameworks/SockPuppetGizmo.framework/SockPuppetGizmo \
@rpath/PlainWatchApp.dylib \
$PRODUCTSDIR/VanillaWatch\ WatchKit\ App.app/_WatchKitStub/WK

install_name_tool -change \
/System/Library/PrivateFrameworks/SockPuppetGizmo.framework/SockPuppetGizmo \
@rpath/PlainWatchApp.dylib \
$PRODUCTSDIR/VanillaWatch\ WatchKit\ App.app/VanillaWatch\ WatchKit\ App
# Sign the .app

❯ codesign -vvvv -f --deep -s "Spencer Elliott" VanillaWatch\ WatchKit\ App.app/Frameworks/PlainWatchApp.dylib 
VanillaWatch WatchKit App.app/Frameworks/PlainWatchApp.dylib: replacing existing signature
VanillaWatch WatchKit App.app/Frameworks/PlainWatchApp.dylib: signed Mach-O thin (armv7k) [PlainWatchApp]
                                                                                                                                                                                               
❯ codesign -vvvv -f --deep -s "Spencer Elliott" VanillaWatch\ WatchKit\ App.app/VanillaWatch\ WatchKit\ App   
VanillaWatch WatchKit App.app/VanillaWatch WatchKit App: replacing existing signature
VanillaWatch WatchKit App.app/VanillaWatch WatchKit App: signed bundle with Mach-O thin (armv7k) [com.elliottsj.VanillaWatch.watchkitapp]
                                                                                                                                                                                               
❯ codesign -vvvv -f --deep -s "Spencer Elliott" VanillaWatch\ WatchKit\ App.app/                           
VanillaWatch WatchKit App.app/: replacing existing signature
VanillaWatch WatchKit App.app/: signed bundle with Mach-O thin (armv7k) [com.elliottsj.VanillaWatch.watchkitapp]

Current error

screenshot 2015-09-19 23 53 18

otool

otool -l $PRODUCTSDIR/VanillaWatch\ WatchKit\ App.app/_WatchKitStub/WK:

VanillaWatch WatchKit App.app/_WatchKitStub/WK:
Load command 0
      cmd LC_SEGMENT
  cmdsize 56
  segname __PAGEZERO
   vmaddr 0x00000000
   vmsize 0x00004000
  fileoff 0
 filesize 0
  maxprot 0x00000000
 initprot 0x00000000
   nsects 0
    flags 0x0
Load command 1
      cmd LC_SEGMENT
  cmdsize 192
  segname __TEXT
   vmaddr 0x00004000
   vmsize 0x00004000
  fileoff 0
 filesize 16384
  maxprot 0x00000005
 initprot 0x00000005
   nsects 2
    flags 0x0
Section
  sectname __stub_helper
   segname __TEXT
      addr 0x00007fcc
      size 0x00000030
    offset 16332
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __symbolstub1
   segname __TEXT
      addr 0x00007ffc
      size 0x00000004
    offset 16380
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000408
 reserved1 0 (index into indirect symbol table)
 reserved2 4 (size of stubs)
Load command 2
      cmd LC_SEGMENT
  cmdsize 328
  segname __DATA
   vmaddr 0x00008000
   vmsize 0x00004000
  fileoff 16384
 filesize 16384
  maxprot 0x00000003
 initprot 0x00000003
   nsects 4
    flags 0x0
Section
  sectname __lazy_symbol
   segname __DATA
      addr 0x00008000
      size 0x00000004
    offset 16384
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000007
 reserved1 1 (index into indirect symbol table)
 reserved2 0
Section
  sectname __nl_symbol_ptr
   segname __DATA
      addr 0x00008004
      size 0x00000008
    offset 16388
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000006
 reserved1 2 (index into indirect symbol table)
 reserved2 0
Section
  sectname __objc_imageinfo
   segname __DATA
      addr 0x0000800c
      size 0x00000008
    offset 16396
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __watchkit
   segname __DATA
      addr 0x00008014
      size 0x00000000
    offset 16404
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Load command 3
      cmd LC_SEGMENT
  cmdsize 56
  segname __LINKEDIT
   vmaddr 0x0000c000
   vmsize 0x00004000
  fileoff 32768
 filesize 9696
  maxprot 0x00000001
 initprot 0x00000001
   nsects 0
    flags 0x0
Load command 4
            cmd LC_DYLD_INFO_ONLY
        cmdsize 48
     rebase_off 32768
    rebase_size 4
       bind_off 32772
      bind_size 24
  weak_bind_off 0
 weak_bind_size 0
  lazy_bind_off 32796
 lazy_bind_size 28
     export_off 32824
    export_size 64
Load command 5
     cmd LC_SYMTAB
 cmdsize 24
  symoff 32892
   nsyms 5
  stroff 32968
 strsize 100
Load command 6
            cmd LC_DYSYMTAB
        cmdsize 80
      ilocalsym 0
      nlocalsym 1
     iextdefsym 1
     nextdefsym 2
      iundefsym 3
      nundefsym 2
         tocoff 0
           ntoc 0
      modtaboff 0
        nmodtab 0
   extrefsymoff 0
    nextrefsyms 0
 indirectsymoff 32952
  nindirectsyms 4
      extreloff 0
        nextrel 0
      locreloff 0
        nlocrel 0
Load command 7
          cmd LC_LOAD_DYLINKER
      cmdsize 28
         name /usr/lib/dyld (offset 12)
Load command 8
     cmd LC_UUID
 cmdsize 24
    uuid F72F628A-5B01-33EB-B932-737B8F8448BD
Load command 9
      cmd LC_VERSION_MIN_WATCHOS
  cmdsize 16
  version 2.0
      sdk 2.0
Load command 10
      cmd LC_SOURCE_VERSION
  cmdsize 16
  version 487.0
Load command 11
       cmd LC_MAIN
   cmdsize 24
  entryoff 16380
 stacksize 0
Load command 12
          cmd LC_LOAD_DYLIB
      cmdsize 52
         name @rpath/PlainWatchApp.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 487.0.0
compatibility version 1.0.0
Load command 13
          cmd LC_LOAD_DYLIB
      cmdsize 76
         name /System/Library/Frameworks/UIKit.framework/UIKit (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 3505.255.4
compatibility version 1.0.0
Load command 14
          cmd LC_LOAD_DYLIB
      cmdsize 84
         name /System/Library/Frameworks/Foundation.framework/Foundation (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1231.0.0
compatibility version 300.0.0
Load command 15
          cmd LC_LOAD_DYLIB
      cmdsize 52
         name /usr/lib/libobjc.A.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 228.0.0
compatibility version 1.0.0
Load command 16
          cmd LC_LOAD_DYLIB
      cmdsize 52
         name /usr/lib/libSystem.B.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1225.0.0
compatibility version 1.0.0
Load command 17
          cmd LC_RPATH
      cmdsize 40
         path @executable_path/Frameworks (offset 12)
Load command 18
      cmd LC_FUNCTION_STARTS
  cmdsize 16
  dataoff 32888
 datasize 4
Load command 19
      cmd LC_DATA_IN_CODE
  cmdsize 16
  dataoff 32892
 datasize 0
Load command 20
      cmd LC_CODE_SIGNATURE
  cmdsize 16
  dataoff 33072
 datasize 9392

otool -l $PLATFORMSDIR/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/Library/Application\ Support/WatchKit/WK:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/Library/Application Support/WatchKit/WK:
Load command 0
      cmd LC_SEGMENT
  cmdsize 56
  segname __PAGEZERO
   vmaddr 0x00000000
   vmsize 0x00004000
  fileoff 0
 filesize 0
  maxprot 0x00000000
 initprot 0x00000000
   nsects 0
    flags 0x0
Load command 1
      cmd LC_SEGMENT
  cmdsize 192
  segname __TEXT
   vmaddr 0x00004000
   vmsize 0x00004000
  fileoff 0
 filesize 16384
  maxprot 0x00000005
 initprot 0x00000005
   nsects 2
    flags 0x0
Section
  sectname __stub_helper
   segname __TEXT
      addr 0x00007fcc
      size 0x00000030
    offset 16332
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __symbolstub1
   segname __TEXT
      addr 0x00007ffc
      size 0x00000004
    offset 16380
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000408
 reserved1 0 (index into indirect symbol table)
 reserved2 4 (size of stubs)
Load command 2
      cmd LC_SEGMENT
  cmdsize 328
  segname __DATA
   vmaddr 0x00008000
   vmsize 0x00004000
  fileoff 16384
 filesize 16384
  maxprot 0x00000003
 initprot 0x00000003
   nsects 4
    flags 0x0
Section
  sectname __lazy_symbol
   segname __DATA
      addr 0x00008000
      size 0x00000004
    offset 16384
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000007
 reserved1 1 (index into indirect symbol table)
 reserved2 0
Section
  sectname __nl_symbol_ptr
   segname __DATA
      addr 0x00008004
      size 0x00000008
    offset 16388
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000006
 reserved1 2 (index into indirect symbol table)
 reserved2 0
Section
  sectname __objc_imageinfo
   segname __DATA
      addr 0x0000800c
      size 0x00000008
    offset 16396
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __watchkit
   segname __DATA
      addr 0x00008014
      size 0x00000000
    offset 16404
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Load command 3
      cmd LC_SEGMENT
  cmdsize 56
  segname __LINKEDIT
   vmaddr 0x0000c000
   vmsize 0x00004000
  fileoff 32768
 filesize 9760
  maxprot 0x00000001
 initprot 0x00000001
   nsects 0
    flags 0x0
Load command 4
            cmd LC_DYLD_INFO_ONLY
        cmdsize 48
     rebase_off 32768
    rebase_size 4
       bind_off 32772
      bind_size 24
  weak_bind_off 0
 weak_bind_size 0
  lazy_bind_off 32796
 lazy_bind_size 28
     export_off 32824
    export_size 64
Load command 5
     cmd LC_SYMTAB
 cmdsize 24
  symoff 32952
   nsyms 5
  stroff 33028
 strsize 100
Load command 6
            cmd LC_DYSYMTAB
        cmdsize 80
      ilocalsym 0
      nlocalsym 1
     iextdefsym 1
     nextdefsym 2
      iundefsym 3
      nundefsym 2
         tocoff 0
           ntoc 0
      modtaboff 0
        nmodtab 0
   extrefsymoff 0
    nextrefsyms 0
 indirectsymoff 33012
  nindirectsyms 4
      extreloff 0
        nextrel 0
      locreloff 0
        nlocrel 0
Load command 7
          cmd LC_LOAD_DYLINKER
      cmdsize 28
         name /usr/lib/dyld (offset 12)
Load command 8
     cmd LC_UUID
 cmdsize 24
    uuid 675ED1EB-BAA0-3453-B7B1-3E69310F40FD
Load command 9
      cmd LC_VERSION_MIN_IPHONEOS
  cmdsize 16
  version 8.2
      sdk 8.2
Load command 10
      cmd LC_SOURCE_VERSION
  cmdsize 16
  version 313.10
Load command 11
       cmd LC_MAIN
   cmdsize 24
  entryoff 16380
 stacksize 0
Load command 12
          cmd LC_LOAD_DYLIB
      cmdsize 52
         name @rpath/PlainWatchApp.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1.0.0
compatibility version 1.0.0
Load command 13
          cmd LC_LOAD_DYLIB
      cmdsize 76
         name /System/Library/Frameworks/UIKit.framework/UIKit (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 3318.93.0
compatibility version 1.0.0
Load command 14
          cmd LC_LOAD_DYLIB
      cmdsize 84
         name /System/Library/Frameworks/Foundation.framework/Foundation (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1142.14.0
compatibility version 300.0.0
Load command 15
          cmd LC_LOAD_DYLIB
      cmdsize 52
         name /usr/lib/libobjc.A.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 228.0.0
compatibility version 1.0.0
Load command 16
          cmd LC_LOAD_DYLIB
      cmdsize 52
         name /usr/lib/libSystem.B.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1214.5.1
compatibility version 1.0.0
Load command 17
          cmd LC_RPATH
      cmdsize 40
         path @executable_path/Frameworks (offset 12)
Load command 18
      cmd LC_FUNCTION_STARTS
  cmdsize 16
  dataoff 32888
 datasize 4
Load command 19
      cmd LC_DATA_IN_CODE
  cmdsize 16
  dataoff 32892
 datasize 0
Load command 20
      cmd LC_DYLIB_CODE_SIGN_DRS
  cmdsize 16
  dataoff 32892
 datasize 60
Load command 21
      cmd LC_CODE_SIGNATURE
  cmdsize 16
  dataoff 33136
 datasize 9392
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment