JavaScriptCore framework ဟာ C base API ဖြစ်ပြီး Mac OSX 10.2 မှာ ကတည်းက စပြီးပါတဲ့ framework တစ်ခုပါ။ iOS 7 နဲ့ Mac OS 10.9 မှာ Apple က JavscriptCore ကို native Objective-C API နဲ့ မိတ်ဆက်ခဲ့ပါတယ်။
အရင်တုန်းက Javascript function တွေကို ခေါ်ဖို့အတွက် UIWebView
ကနေ တဆင့်
stringByEvaluatingJavaScriptFromString:
နဲ့ ခေါ်ရပါတယ်။ JavaScriptCore framework ဟာ developer တွေကို တွေကို Objective-C ကနေ full javascript runtime access လုပ်ခွင့်ပေးထားပါတယ်။
Javascript ဟာ JSVirtualMachine
machine မှာ run ထားပါတယ်။ JSVirtualMachine
ဟာ light weight ဖြစ်ပြီးတော့ multithreaded javascript တွေကို အလုပ်လုပ်ပေးနိုင်တယ်။ JSVirtualMachine
ထဲမှာ JSContext
တွေ ရှိပါတယ်။ JSContexts
ဟာ Javascript runtime environment နဲ့ ချိတ်ဆက်ဆောင်ရွက်ပေးပြီးတော့ javascript က global object တွေကို access လုပ်နိုင်တယ်သလို script တွေကိုလည်း execute လုပ်ပေးပါတယ်။
JSContext *context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];
context[@"a"] = @5;
အထက်ပါ code မှာ ဆိုရင် javascript က global variable a က နံပတ် ၅ ဖြစ်တယ်လို့ ဆိုထားပါတယ်။ Javascript က variable ကို ပြန်လိုချင်ရင်တော့ JSValue နဲ့ လက်ခံရပါတယ်။
JSValue *aValue = context[@"a"];
double a = [aValue toDouble];
NSLog(@"%.0f", a);
javascript ကို evaluateScript
နဲ့လည်း တိုက်ရိုက် run လို့ရပါတယ်။
[context evaluateScript:@"a = 10"];
JSValue *newAValue = context[@"a"];
NSLog(@"%.0f", [newAValue toDouble]);
ကျွန်တော်တို့တွေ javascript function ကို objective c မှာလည်း ပြန်ပြီး အသုံးချလို့ရတယ်။
[context evaluateScript:@"var square = function(x) {return x*x;}"];
JSValue *squareFunction = context[@"square"];
NSLog(@"%@", squareFunction);
JSValue *aSquared = [squareFunction callWithArguments:@[context[@"a"]]];
NSLog(@"a^2: %@", aSquared);
JSValue *nineSquared = [squareFunction callWithArguments:@[@9]];
NSLog(@"9^2: %@", nineSquared);
အဲဒီ အခါ အောက်ကလို မျိုး result ရလာပါလိမ့်မယ်။
JSThing[53327:a0b] function (x) {return x*x;}
JSThing[53282:a0b] a^2: 25
JSThing[53282:a0b] 9^2: 81
-callWithArguments
method နဲ့ JSValue ကို NSArray နဲ့ argument တွေ ပို့ပေးလို့ရပါတယ်။ အပေါ်က example မှာ argument က ၁ ခုပဲ ဖြစ်တဲ့အတွက် array အခန်းက ၁ ခုပဲ ဖြစ်နေတာပါ။ တကယ်လို့ ၂ ခု သာ ဆိုရင် အခန်း ၂ ခန်းဖြစ်နေပါလိမ့်မယ်။
ဒါ့အပြင် JSContext
ဟာ objective-c function ကို parse လုပ်ပေးနိုင်ပါတယ်။
context[@"factorial"] = ^(int x) {
int factorial = 1;
for (; x > 1; x--) {
factorial *= x;
}
return factorial;
};
[context evaluateScript:@"var fiveFactorial = factorial(5);"];
JSValue *fiveFactorial = context[@"fiveFactorial"];
NSLog(@"5! = %@", fiveFactorial);
NSLog က အောက်ကလို ထွက်လာပါမယ်။
JSThing[53327:a0b] 5! = 120
Objective-C data type ကို jsvalue အနေနဲ့ parse လုပ်တဲ့ အခါ javacsript မှာ အောက်ကလို data type ပြောင်းသွားပါတယ်။
Objective-C Type | Javascript Type |
---|---|
nil | undefined |
NSNull | null |
NSString | string |
NSNumber | number , boolean |
NSDictionary | Object object |
NSArray | Array object |
NSDate | Date object |
NSBlock | Function object |
id | Wrapper object |
Class | Constructor object |
ကိုယ်ပိုင် class တစ်ခုကို javascript မှာ parse လုပ်ဖို့ အတွက် JSExport ကို အသုံးပြုရပါတယ်။ အောက်မှာ ဥပမာလေး ကြည့်ပါ။
@protocol ThingJSExports <JSExport>
@property (nonatomic, copy) NSString *name;
@end
@interface Thing : NSObject <ThingJSExports>
@property (nonatomic, copy) NSString *name;
@property (nonatomic) NSInteger number;
@end
@implementation Thing
- (NSString *)description {
return [NSString stringWithFormat:@"%@: %d", self.name, self.number];
}
@end
ThingJSExports
ဟာ JSExport
ကနေ inherits လုပ်ထားပါတယ်။
Thing *thing = [[Thing alloc] init];
thing.name = @"Alfred";
thing.number = 3;
context[@"thing"] = thing;
JSValue *thingValue = context[@"thing"];
Thing object ကို JSContext
မှာ ထည့်လိုက်တာ တွေ့ပါလိမ့်မယ်။ JSValue
result က ဘာတွေ ထွက်လာမလဲ ဆိုာတကို အောက်ကလို ကြည့်နိုင်ပါတယ်။
NSLog(@"Thing: %@", thing);
NSLog(@"Thing JSValue: %@", thingValue);
Result ဟာ
JSThing[53344:a0b] Thing: Alfred: 3
JSThing[53344:a0b] Thing JSValue: Alfred: 3
ဖြစ်နေတာကို တွေ့ပါလိမ့်မယ်။ Value ပြောင်းပြီး ကြည့်ရအောင်။
thing.name = @"Betty";
thing.number = 8;
NSLog(@"Thing: %@", thing);
NSLog(@"Thing JSValue: %@", thingValue);
JSThing[53344:a0b] Thing: Betty: 8
JSThing[53344:a0b] Thing JSValue: Betty: 8
Javascript ကနေ thing object ကို variable ပြောင်းမယ်ဆိုရင်
[context evaluateScript:@"thing.name = \"Carlos\"; thing.number = 5"];
NSLog(@"Thing: %@", thing);
NSLog(@"Thing JSValue: %@", thingValue);
NSLog မှာ အောက်ကလို ပေါ်ပါလိမ့်မယ်။
Thing: Carlos: 8
Thing JSValue: Carlos: 8
JavaScripteCore framework ဟာ WebKit ရဲ့ အစိတ်အပိုင်းတစ်ခုဖြစ်ပြီး open-source project ပါ။ သူရဲ့ source code ကို ဒီမှာ ကြည့်နိုင်ပါတယ်။