Slide 1

Slide 1 text

+BWB4DSJQU$PSFGSBNFXPSLͰ Ͱ͖Δ͜ͱ

Slide 2

Slide 2 text

؛઒ࠀݾ http://kishikawakatsumi.com Twitter @k_katsumi 24/7 twenty-four seven http://d.hatena.ne.jp/KishikawaKatsumi/

Slide 3

Slide 3 text

ΞδΣϯμ w +BWB4DSJQU$PSFGSBNFXPSLͷ֓ཁͱ࢖͍ํ w 0CKFDUJWF$3VOUJNF"1*ͷ׆༻ํ๏ w +BWB4DSJQU#SJEHFͷ঺հ

Slide 4

Slide 4 text

ؔ࿈هࣄ w +BWB4DSJQU͚ͩͰJ04ͷ6*Λॻ͍ͯΈΔ w IUUQEIBUFOBOFKQ,JTIJLBXB,BUTVNJ w +BWB4DSJQUͰJ04ΞϓϦ͕ॻ͚ΔϥΠϒϥϦ+BWB4DSJQU#SJEHFΛ ެ։͠·ͨ͠ w IUUQEIBUFOBOFKQ,JTIJLBXB,BUTVNJ

Slide 5

Slide 5 text

αϯϓϧίʔυ w IUUQTHJUIVCDPNLJTIJLBXBLBUTVNJEPXOMPBEBCMFJPTBQQT w IUUQTHJUIVCDPNLJTIJLBXBLBUTVNJ+BWB4DSJQU#SJEHF

Slide 6

Slide 6 text

+BWB4DSJQU$PSFGSBNFXPSL

Slide 7

Slide 7 text

0CKFDUJWF$+BWB4DSJQUϒϦοδ w 0CKFDUJWF$͔Β+BWB4DSJQUΛ࣮ߦ͢Δ w +BWB4DSJQU͔Β0CKFDUJWF$Λ࣮ߦ͢Δ w 0CKFDUJWF$ͱ+BWB4DSJQUͷΦϒδΣΫτͷ ૬ޓม׵

Slide 8

Slide 8 text

֓ཁ

Slide 9

Slide 9 text

! JSContext *context = [[JSContext alloc] init]; ! JSValue *result = [context evaluateScript:@"2 + 8"]; NSLog(@"%d", result.toInt32);

Slide 10

Slide 10 text

JSContext *context = [[JSContext alloc] init]; ! context[@"factorial"] = ^(int x) { int factorial = 1; for (; x > 1; x--) { factorial *= x; } return factorial; }; ! JSValue *result = [context evaluateScript:@"factorial(5);"]; NSLog(@"%d", result.toInt32);

Slide 11

Slide 11 text

JSContext *context = [[JSContext alloc] init]; ! context[@"factorial"] = ^(int x) { int factorial = 1; for (; x > 1; x--) { factorial *= x; } return factorial; }; ! JSValue *function = context[@“factorial"]; ! JSValue *result = [function callWithArguments:@[@(5)]]; NSLog(@"%d", result.toInt32);

Slide 12

Slide 12 text

JSContext *context = [[JSContext alloc] init]; [context evaluateScript: @"function sum(a, b) { return a + b; }" ]; ! JSValue *function = context[@“sum"]; ! JSValue *result = [function callWithArguments:@[@(2), @(3)]] NSLog(@"%d", result.toInt32);

Slide 13

Slide 13 text

w +47JSUVBM.BDIJOF w +4$POUFYU w +47BMVF w +4.BOBHFE7BMVF w +4&YQPSU

Slide 14

Slide 14 text

w +47JSUVBM.BDIJOF γϯάϧεϨουͷ+4Ծ૝Ϛγϯ w +4$POUFYU +4ͷ࣮ߦίϯςΩετʢΦϒδΣΫτͷ؅ཧʣ w +47BMVF +4ΦϒδΣΫτͷϥούʔ

Slide 15

Slide 15 text

+47JSUVBM.BDIJOF +4$POUFYU +47BMVF +47JSUVBM.BDIJOF +47JSUVBM.BDIJOF +47BMVF +4$POUFYU +47BMVF +47BMVF

Slide 16

Slide 16 text

࢖͍Ͳ͜Ζ

Slide 17

Slide 17 text

0CKFDUJWF$+BWB4DSJQU

Slide 18

Slide 18 text

0CKFDUJWF$+BWB4DSJQU w Ұ෦ͷϩδοΫΛ+BWB4DSJQUͰهड़ 8FC΍"OESPJEͳͲผͷϓϥοτϑΥʔϜͱڞ௨Խ͢Δͱ͔ w +BWB4DSJQUͰॻ͔ΕͨϥΠϒϥϦΛ࢖͏

Slide 19

Slide 19 text

w ͸ͯͳه๏1BSTFS UFYUIBUFOBKT IUUQUFDIOJUPZPODPNKBWBTDSJQUBQQMJDBUJPOUFYUIBUFOBEPXOMPBEIUNM w 5FYUJMF1BSTFS UFYUJMFKT IUUQTHJUIVCDPNCPSHBSUFYUJMFKT w +40/ͷѹॖ +40/) IUUQTHJUIVCDPN8FC3FqFDUJPO+40/) +BWB4DSJQUͰॻ͔ΕͨϥΠϒϥϦΛ࢖͏

Slide 20

Slide 20 text

͸ͯͳه๏1BSTFS

Slide 21

Slide 21 text

NSBundle *bundle = [NSBundle mainBundle]; NSString *path = [bundle pathForResource:@"text-hatena" ofType:@"js"]; NSString *script = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; ! JSContext *context = [[JSContext alloc] init]; [context evaluateScript:script]; [context evaluateScript:@"var parser = new TextHatena();"]; ! JSValue *parser = context[@"parser"]; ! NSString *text = [NSString stringWithContentsOfFile: [bundle pathForResource:@“sample” ofType:@“txt"] encoding:NSUTF8StringEncoding error:nil]; ! NSLog(@"%@", [parser invokeMethod:@"parse" withArguments:@[text]]); ! return YES;

Slide 22

Slide 22 text

*1384756611*[Objective-C][iOS]iOSΞϓϦέʔγϣϯͰΩʔϘʔυγϣʔτΧοτʹରԠ͢Δ ↓ ΑΓஸೡͳهࣄ͸ͪ͜ΒͰެ։͍ͯ͠·͢ɻ - [http://mobiletou.ch/2013/11/ ios%E3%82%A2%E3%83%97%E3%83%AA%E3%81%A7%E5%A4%96%E9%83%A8%E3%82%AD%E3%83%BC%E3%83%9C%E3 %83%BC%E3%83%89%E3%81%8B%E3%82%89%E3%81%AE%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB %E3%83%83%E3%83%88:title=iOSΞϓϦͰ֎෦ΩʔϘʔυ͔ΒͷγϣʔτΧοτʹରԠ͢Δํ๏ - iOSΞϓϦ։ ൃ͜΅Ε࿩] ! ! iOS 7ͷSafari΍ϝʔϧͰ͸֎෦ΩʔϘʔυΛ࢖༻ͨ͠ࡍʹར༻Ͱ͖ΔͰ͖ΔγϣʔτΧοτ͕[http:// www.appbank.net/2013/11/08/iphone-news/696998.php:title=ҎલΑΓॆ࣮ͨ͜͠ͱ͕࿩୊ʹͳΓ·͠ ͨɻ] ! ! iOS 7Ͱ͸ΩʔϘʔυγϣʔτΧοτΛ࣮૷͢ΔͨΊͷAPI͕௥Ճ͞Ε͍ͯΔͷͰɺαʔυύʔςΟͷΞϓϦέʔγϣ ϯ΋ΩʔϘʔυγϣʔτΧοτʹରԠ͢Δ͜ͱ͕Ͱ͖·͢ɻ ! ! ಛఆͷΩʔϘʔυγϣʔτΧοτʹԠ౴͢Δʹ͸ԼهͷϓϩύςΟΛ࣮૷͠·͢ɻ >|objc| @property(nonatomic, readonly) NSArray *keyCommands ||<

Slide 23

Slide 23 text

o- [][]iOSΞϓϦέʔγϣϯͰΩʔϘʔυγϣʔτ ΧοτʹରԠ͢Δ

↓ ΑΓஸೡͳهࣄ͸ͪ͜ΒͰެ։͍ͯ͠·͢ɻ

  • [http://mobiletou.ch/2013/11/ ios%E3%82%A2%E3%83%97%E3%83%AA%E3%81%A7%E5%A4%96%E9%83%A8%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%8 3%89%E3%81%8B%E3%82%89%E3%81%AE%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88:tit le=iOSΞϓϦͰ֎෦ΩʔϘʔυ͔ΒͷγϣʔτΧοτʹରԠ͢Δํ๏ - iOSΞϓϦ։ൃ͜΅Ε࿩]

iOS 7ͷSafari΍ϝʔϧͰ͸֎෦ΩʔϘʔυΛ࢖༻ͨ͠ࡍʹར༻Ͱ͖ΔͰ͖ΔγϣʔτΧοτ͕[http:// www.appbank.net/2013/11/08/iphone-news/696998.php:title=ҎલΑΓॆ࣮ͨ͜͠ͱ͕࿩୊ʹͳΓ·ͨ͠ɻ]


iOS 7Ͱ͸ΩʔϘʔυγϣʔτΧοτΛ࣮૷͢ΔͨΊͷAPI͕௥Ճ͞Ε͍ͯΔͷͰɺαʔυύʔςΟͷΞϓϦέʔγϣϯ΋ ΩʔϘʔυγϣʔτΧοτʹରԠ͢Δ͜ͱ͕Ͱ͖·͢ɻ


ಛఆͷΩʔϘʔυγϣʔτΧοτʹԠ౴͢Δʹ͸ԼهͷϓϩύςΟΛ࣮૷͠·͢ɻ

@property(nonatomic, readonly) NSArray *keyCommands

Slide 24

Slide 24 text

5FYUJMF1BSTFS

Slide 25

Slide 25 text

NSBundle *bundle = [NSBundle mainBundle]; NSString *path = [bundle pathForResource:@"textile" ofType:@"js"]; NSString *script = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; ! JSContext *context = [[JSContext alloc] init]; [context evaluateScript:script]; ! JSValue *func = context[@"textile"]; ! NSString *text = [NSString stringWithContentsOfFile: [bundle pathForResource:@"sample" ofType:@“textile"] encoding:NSUTF8StringEncoding error:nil]; ! NSLog(@"%@", [func callWithArguments:@[text]]);

Slide 26

Slide 26 text

ࠓճ͸ɺεϖγϟϧηογϣϯͱͯ͠Evernoteຊ͔ࣾΒMac൛EvernoteͷUIͷϦχϡʔΞϧͷࢦشΛ͞ Ε·ͨ͠["Jack Hirsch":https://twitter.com/Jackolicious]͞Μʹ͖͍͖ͯͨͩɺഎܠ΍։ ൃख๏ͳͲΛ͓࿩͍͖ͨͩ·͢ɻ ͢΂ͯͷ։ൃऀʹͱͬͯඇৗʹ༗ҙٛͳ࣌ؒʹͳΔͱࢥ͍·͢ͷͰͥͻ͓ӽ͍ͩ͘͠͞ɻ ! ! h3. ελοϑืू ! ౰೔ɺձ৔ͷ४උ΍ड෇ͳͲΛख఻ͬͯͩ͘͞Δ͔ͨΛืू͍ͨ͠·͢ɻख఻ͬͯ΋͍͍Αɺͱ͍͏͔ͨ ͕͍Βͬ͠Ό͍·ͨ͠Β͝࿈བྷ͍ͩ͘͞·ͤɻ ! ["lesamoureuses":https://twitter.com/lesamoureuses] ["huin":https://twitter.com/huin] ["myb":https://twitter.com/myb] ["nun_":https://twitter.com/nun_] ["KohsakuNishida":https://twitter.com/KohsakuNishida] ["৿ౢେथ":https://www.facebook.com/hiroki.with.omnia] ! ! *։৔ 12:30* **৔ॴ** גࣜձࣾVOYAGE GROUP (౦ژ౎ौ୩۠ਆઘொ8-16 ौ୩ϑΝʔετϓϨΠε8F)

Slide 27

Slide 27 text

ࠓճ͸ɺεϖγϟϧηογϣϯͱͯ͠Evernoteຊ͔ࣾΒMac൛EvernoteͷUIͷϦχϡʔΞ ϧͷࢦشΛ͞Ε·ͨ͠Jack Hirsch͞Μʹ͖͍͖ͯͨͩɺഎܠ΍։ൃख๏ͳͲΛ͓࿩͍͖ͨͩ·͢ɻ
͢΂ͯͷ։ൃऀʹͱͬͯඇৗʹ༗ҙٛͳ࣌ؒʹͳΔͱࢥ͍·͢ͷͰͥͻ͓ӽ͍ͩ͘͠͞ɻ

ελοϑืू

౰೔ɺձ৔ͷ४උ΍ड෇ͳͲΛख఻ͬͯͩ͘͞Δ͔ͨΛืू͍ͨ͠·͢ɻख఻ͬͯ΋͍͍ Αɺͱ͍͏͔͕͍ͨΒͬ͠Ό͍·ͨ͠Β͝࿈བྷ͍ͩ͘͞·ͤɻ

lesamoureuses
huin
myb
nun_
KohsakuNishida
৿ౢେथ

։৔ 12:30
৔ॴ
גࣜձࣾVOYAGE GROUP span>
(౦ژ౎ौ୩۠ਆઘொ8-16 ौ୩ϑΝʔετϓϨΠε8F)

Slide 28

Slide 28 text

+BWB4DSJQU0CKFDUJWF$

Slide 29

Slide 29 text

+4&YQPSU

Slide 30

Slide 30 text

+BWB4DSJQUʹެ։͢Δ 0CKFDUJWF$ͷΠϯλʔϑΣʔε

Slide 31

Slide 31 text

@protocol JSUIWindow ! @property (nonatomic) CGRect frame; @property (nonatomic) UIColor *backgroundColor; ! + (id)new; - (void)makeKeyAndVisible; ! @end

Slide 32

Slide 32 text

@interface JSUIWindow : UIWindow ! @end ! @implementation JSUIWindow ! @end

Slide 33

Slide 33 text

JSContext *context = [[JSContext alloc] init]; context[@"JSUIWindow"] = [JSUIWindow class]; JSContext *context = [[JSContext alloc] init]; context[@"JSUIWindow"] = [JSUIWindow class]; ! [context evaluateScript:@"var window = JSUIWindow.new();"]; ! JSValue *value = context[@"window"]; NSLog(@"%@", value.toObject);

Slide 34

Slide 34 text

طଘͷΫϥεΛ+4&YQPSUʹ ద߹ͤ͞Δ

Slide 35

Slide 35 text

! class_addProtocol([UIWindow class], @protocol(JSUIWindow)); JSContext *context = [[JSContext alloc] init]; context[@"UIWindow"] = [UIWindow class]; [context evaluateScript:@"var window = UIWindow.new();"]; ! JSValue *value = context[@"window"]; NSLog(@"%@", value.toObject);

Slide 36

Slide 36 text

ಈతʹ΍ͬͯΈΔ ʢͰ͖ͳ͍ʣ

Slide 37

Slide 37 text

static void setup(JSContext *context) { const char *prefix = "JSUI"; unsigned int numberOfClasses; Class *classes = objc_copyClassList(&numberOfClasses); for (unsigned int i = 0; i < numberOfClasses; i++) { Class cls = classes[i]; const char *className = class_getName(cls); NSString *name = @(className); char protocolName[512]; snprintf(protocolName, sizeof(protocolName), "%s%s", prefix, className); Protocol *proto = objc_allocateProtocol(protocolName); traverce_class(proto, cls); protocol_addProtocol(proto, @protocol(JSExport)); objc_registerProtocol(proto); class_addProtocol(cls, proto); context[name] = cls; } free(classes); } 4*("#35

Slide 38

Slide 38 text

+BWB4DSJQU#SJEHF

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

@protocol JSBUIView; ! @protocol JSBUIAlertView ! @property (nonatomic, readonly) NSInteger numberOfButtons; @property (nonatomic, readonly, getter = isVisible) BOOL visible; @property (nonatomic) NSInteger cancelButtonIndex; @property (nonatomic, copy) NSString *title; @property (nonatomic, copy) NSString *message; @property (nonatomic, assign) id delegate; @property (nonatomic, assign) UIAlertViewStyle alertViewStyle; @property (nonatomic, readonly) NSInteger firstOtherButtonIndex; ! - (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles , ...; - (NSInteger)addButtonWithTitle:(NSString *)title; - (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex; - (void)show; - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated: (BOOL)animated; - (UITextField *)textFieldAtIndex:(NSInteger)textFieldIndex; ! #pragma clang diagnostic pop ! @end

Slide 41

Slide 41 text

@protocol JSBUIView ! @property (nonatomic, getter = isOpaque) BOOL opaque; @property (nonatomic) CGRect frame; @property (nonatomic, getter = isHidden) BOOL hidden; @property (nonatomic) BOOL autoresizesSubviews; @property (nonatomic, readonly, copy) NSArray *subviews; ! ! + (Class)layerClass; + (void)beginAnimations:(NSString *)animationID context:(void *)context; + (void)commitAnimations;

Slide 42

Slide 42 text

@protocol JSBNSObject ! - (BOOL)isEqual:(id)object; - (NSUInteger)hash; ! - (Class)superclass; - (Class)class; ! - (BOOL)isProxy; ! - (BOOL)isKindOfClass:(Class)aClass; - (BOOL)isMemberOfClass:(Class)aClass; - (BOOL)conformsToProtocol:(Protocol *)aProtocol; ! - (NSString *)description; - (NSString *)debugDescription; ! + (void)load; ! + (void)initialize; - (id)init; ! + (id)new; + (id)allocWithZone:(struct _NSZone *)zone;

Slide 43

Slide 43 text

JSContext *context = [JSBScriptingSupport globalContext]; ! [context addScriptingSupport:@“AssetsLibrary"]; [context addScriptingSupport:@"Accounts"]; [context addScriptingSupport:@"Social"]; [context addScriptingSupport:@“MapKit"];

Slide 44

Slide 44 text

[context evaluateScript: @"var window = UIWindow.alloc().initWithFrame(UIScreen.mainScreen().bounds);" @"window.backgroundColor = UIColor.whiteColor();" @"" @"var navigationController = UINavigationController.new();" @"" @"var tableViewController = UITableViewController.new();" @"tableViewController.navigationItem.title = 'JavaScriptBridge';" @"navigationController.viewControllers = [tableViewController];" @"" @"window.rootViewController = navigationController;" @"" @"window.makeKeyAndVisible();" @"" @"var alertView = UIAlertView.new();" @"alertView.message = 'Hello JavaScriptBridge!';" @"alertView.addButtonWithTitle('OK');" @"alertView.show();" ];

Slide 45

Slide 45 text

UISlider *slider = [[UISlider alloc] initWithFrame:frame]; slider.backgroundColor = [UIColor clearColor]; slider.minimumValue = 0.0; slider.maximumValue = 100.0; slider.continuous = YES; slider.value = 50.0; var slider = UISlider.alloc().initWithFrame(frame); slider.backgroundColor = UIColor.clearColor(); slider.minimumValue = 0.0; slider.maximumValue = 100.0; slider.continuous = true; slider.value = 50.0; ϓϩύςΟΞΫηε

Slide 46

Slide 46 text

UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; var window = UIWindow.alloc().initWithFrame(UIScreen.mainScreen().bounds); ϝιουݺͼग़͠

Slide 47

Slide 47 text

UIView *view = [UIView new]; view.frame = CGRectMake(20, 80, 280, 80); ! CGFloat x = view.frame.origin.x; CGFloat width = view.frame.size.width; var view = UIView.new(); view.frame = {x: 20, y: 80, width: 280, height: 80}; ! var x = view.frame.x; var width = view.frame.width; ߏ଄ମ

Slide 48

Slide 48 text

ಠࣗͷ֦ு

Slide 49

Slide 49 text

Ϋϥεఆٛ

Slide 50

Slide 50 text

var MainViewController = JSB.defineClass('MainViewController : UITableViewController', { // Instance Method Definitions viewDidLoad: function() { self.navigationItem.title = 'UICatalog'; }, viewWillAppear: function(animated) { self.tableView.reloadData(); } }, { // Class Method Definitions attemptRotationToDeviceOrientation: function() { ... } });

Slide 51

Slide 51 text

Class cls = objc_allocateClassPair(NSClassFromString(parentClassName), className.UTF8String, 0); objc_registerClassPair(cls); ! Class superClass = class_getSuperclass(cls); if (superClass) { setupForwardingImplementations(cls, superClass, instanceMembers, staticMembers); } ! NSString *types; BOOL result; ! Class metaClass = objc_getMetaClass(className.UTF8String); ! types = [NSString stringWithFormat: @"%s%s%s%s", @encode(NSMethodSignature), @encode(id), @encode(SEL), @encode(SEL)]; result = class_addMethod(cls, @selector(methodSignatureForSelector:), (IMP)methodSignatureForSelector, types.UTF8String); result = class_addMethod(metaClass, @selector(methodSignatureForSelector:), (IMP)methodSignatureForSelector, types.UTF8String); ! types = [NSString stringWithFormat: @"%s%s%s%s", @encode(void), @encode(id), @encode(SEL), @encode(NSInvocation)]; result = class_addMethod(cls, @selector(forwardInvocation:), (IMP)forwardInvocation, types.UTF8String); result = class_addMethod(metaClass, @selector(forwardInvocation:), (IMP)forwardInvocation, types.UTF8String); ! types = [NSString stringWithFormat: @"%s%s%s%s", @encode(BOOL), @encode(id), @encode(SEL), @encode(SEL)]; result = class_addMethod(cls, @selector(respondsToSelector:), (IMP)respondsToSelector, types.UTF8String); result = class_addMethod(metaClass, @selector(respondsToSelector:), (IMP)respondsToSelector, types.UTF8String); ! for (NSString *protocol in [protocols componentsSeparatedByString:@","]) { class_addProtocol(cls, NSProtocolFromString([protocol stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]])); } ! class_addProtocol(cls, @protocol(JSBNSObject)); ! NSString *key = mangledNameFromClass(cls); globalContext[key] = cls; globalContext[key][JSBInstanceMembersKey] = instanceMembers; globalContext[key][JSBStaticMembersKey] = staticMembers; ! return cls;

Slide 52

Slide 52 text

Class cls = objc_allocateClassPair(NSClassFromString(parentClassName), className.UTF8String, 0); objc_registerClassPair(cls); ΫϥεΛಈతʹఆٛ

Slide 53

Slide 53 text

NSString *types; BOOL result; ! types = [NSString stringWithFormat: @“%s%s%s%s", @encode(NSMethodSignature), @encode(id), @encode(SEL), @encode(SEL)]; ! result = class_addMethod(cls, @selector(methodSignatureForSelector:), (IMP)methodSignatureForSelector, types.UTF8String); ΫϥεʹϝιουΛ௥Ճ ʢΠϯελϯεϝιουʣ

Slide 54

Slide 54 text

NFUIPE4JHOBUVSF'PS4FMFDUPS GPSXBSE*OWPDBUJPO SFTQPOET5P4FMFDUPS ϝιουݺͼग़͠Λసૹ

Slide 55

Slide 55 text

NSMethodSignature *methodSignatureForSelector(id self, SEL _cmd, SEL selector) { NSMethodSignature *methodSignature = nil; Class cls = object_getClass(self); if (class_isMetaClass(cls)) { methodSignature = [cls instanceMethodSignatureForSelector:selector]; if (methodSignature) { return methodSignature; } } else { methodSignature = [cls instanceMethodSignatureForSelector:selector]; if (methodSignature) { return methodSignature; } } NSUInteger numberOfArguments = [[NSStringFromSelector(selector) componentsSeparatedByString:@":"] count] - 1; return [NSMethodSignature signatureWithObjCTypes:[[@"@@:" stringByPaddingToLength:numberOfArguments + 3 withString:@"@" startingAtIndex:0] UTF8String]]; } ϝιουݺͼग़͠Λసૹ

Slide 56

Slide 56 text

BOOL respondsToSelector(id self, SEL _cmd, SEL selector) { NSString *propertyName = propertyNameFromSelector(selector); JSValue *function = propertyForObject(self, propertyName); return !function.isUndefined; } ϝιουݺͼग़͠Λసૹ

Slide 57

Slide 57 text

void forwardInvocation(id self, SEL _cmd, NSInvocation *invocation) { JSContext *context = [JSBScriptingSupport globalContext]; if ([[self superclass] instancesRespondToSelector:invocation.selector]) { invokeSuper(invocation); } id currentSelf = context[@"self"]; context[@"self"] = self; NSString *propertyName = propertyNameFromSelector(invocation.selector); JSValue *function = propertyForObject(self, propertyName); if (!function.isUndefined) { NSArray *arguments = extractArguments(invocation); JSValue *returnValue = [function callWithArguments:arguments]; setReturnValue(returnValue, invocation); } context[@"self"] = currentSelf; } ϝιουݺͼग़͠Λసૹ

Slide 58

Slide 58 text

NSString *types; BOOL result; ! Class metaClass = objc_getMetaClass(className.UTF8String); ! types = [NSString stringWithFormat: @"%s%s%s%s", @encode(NSMethodSignature), @encode(id), @encode(SEL), @encode(SEL)]; ! result = class_addMethod(metaClass, @selector(methodSignatureForSelector:), (IMP)methodSignatureForSelector, types.UTF8String); ΫϥεʹϝιουΛ௥Ճ ʢΫϥεϝιουʣ

Slide 59

Slide 59 text

JSValue *propertyForObject(id obj, NSString *propertyName) { JSContext *context = [JSBScriptingSupport globalContext]; JSValue *properties = nil; Class cls = object_getClass(obj); if (class_isMetaClass(cls)) { properties = context[mangledNameFromClass(obj)][JSBStaticMembersKey]; } else { properties = context[mangledNameFromClass(cls)][JSBInstanceMembersKey]; } return properties[propertyName]; } JEܕͷΦϒδΣΫτ͕ ΫϥεΦϒδΣΫτ͔Ͳ͏͔

Slide 60

Slide 60 text

unsigned int numberOfInstanceMethods = 0; Method *instanceMethods = class_copyMethodList(cls, &numberOfInstanceMethods); for (unsigned int i = 0; i < numberOfInstanceMethods; i++) { Method method = instanceMethods[i]; struct objc_method_description *description = method_getDescription(method); NSString *propertyName = propertyNameFromSelector(description->name); JSValue *function = instanceFunctions[propertyName]; if (!function.isUndefined) { class_addMethod(targetClass, description->name, _objc_msgForward, description->types); } } if (instanceMethods) { free(instanceMethods); } ΫϥεʹϝιουΛ௥Ճ ʢΦʔόʔϥΠυʣ

Slide 61

Slide 61 text

class_addMethod(targetClass, description->name, _objc_msgForward, description->types); ϝιουݺͼग़͠Λసૹ

Slide 62

Slide 62 text

@PCKD@NTH'PSXBSE

Slide 63

Slide 63 text

! OBJC_EXPORT id _objc_msgForward(id receiver, SEL sel, ...) __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

Slide 64

Slide 64 text

void forwardInvocation(id self, SEL _cmd, NSInvocation *invocation) { JSContext *context = [JSBScriptingSupport globalContext]; if ([[self superclass] instancesRespondToSelector:invocation.selector]) { invokeSuper(invocation); } id currentSelf = context[@"self"]; context[@"self"] = self; NSString *propertyName = propertyNameFromSelector(invocation.selector); JSValue *function = propertyForObject(self, propertyName); if (!function.isUndefined) { NSArray *arguments = extractArguments(invocation); JSValue *returnValue = [function callWithArguments:arguments]; setReturnValue(returnValue, invocation); } context[@"self"] = currentSelf; } ʢͳΜͱͳ͘ʣ+4ͱ0CK$͕ର࿩Ͱ͖Δ

Slide 65

Slide 65 text

Ϟδϡʔϧ ʢͳΜͪΌͬͯʣ

Slide 66

Slide 66 text

var ButtonsViewController = JSB.require('buttonsViewController'); var ControlsViewController = JSB.require('controlsViewController'); var WebViewController = JSB.require('webViewController'); var MapViewController = JSB.require('mapViewController'); ! var MainViewController = JSB.defineClass('MainViewController : UITableViewController', { viewDidLoad: function() { self.navigationItem.title = 'UICatalog'; ... }); JSB.exports = MainViewController;

Slide 67

Slide 67 text

w 8FCΤϯδχΞ w J04ΤϯδχΞ w σβΠφʔ ! w ϢϏϨδΛࢧ͑Δٕज़ w IUUQBLJTVUFDPNCMPHQPTUIUNM w ब׆೔ه ϢϏϨδ๚໰ w IUUQMBJTPIBUFOBCMPHDPNFOUSZ&##&###&"&"@ @&"&&"$&#&"""&'