objectc 与 js 交互

Execute Javascript in iOS Applications

In this tutorial, I have covered How to execute JavaScript in iOS / Objective-C. You can execute JavaScript in iOS applications with the help of JavaScriptCore.framework. This framework is supported in iOS7 & OSX 10.9

List of features supported by Javascript.framework
a) Evaluate JavaScript code in Objective-C
b) Access JavaScript Variables in Objective-C
c) Access JavaScript functions and execute them in Objective-C
d) Execute Objective-C code from JavaScript
e) Export Objective-C classes and use them in JavaScript.

Download the source code: Download source of Execute JavaScript in iOS Application

To access JavaScript framework, you need to include the header file

1
#import <JavaScriptCore/JavaScriptCore.h>

List of Main Classes supported by framework:
JSContext : For any javascript operations you need JSContext.

1
JSContext  *context = [[ JSContext  alloc ]  init ];

JSValue : JSValue holds JavaScript values,variables and functions. List of main methods in JSValue.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Convert this value to a corresponding Objective-C object, according to the
// conversion specified above.
- ( id )toObject;
 
// Convert this value to a corresponding Objective-C object, if the result is
// not of the specified class then nil will be returned.
- ( id )toObjectOfClass:(Class)expectedClass;
 
// The value is copied to a boolean according to the conversion specified by the
// JavaScript language.
- ( BOOL )toBool;
 
// The value is copied to a number according to the conversion specified by the
// JavaScript language.
- ( double )toDouble;
 
// The value is copied to an integer according to the conversion specified by
// the JavaScript language.
- (int 3 2 _t)toInt 3 2 ;
 
// The value is copied to an integer according to the conversion specified by
// the JavaScript language.
- (uint 3 2 _t)toUInt 3 2 ;
 
// If the value is a boolean, a NSNumber value of @YES or @NO will be returned.
// For all other types the value will be copied to a number according to the
// conversion specified by the JavaScript language.
- ( NSNumber  *)toNumber;
 
// The value is copied to a string according to the conversion specified by the
// JavaScript language.
- ( NSString  *)toString;
 
// The value is converted to a number representing a time interval since 1970,
// and a new NSDate instance is returned.
- ( NSDate  *)toDate;
 
// If the value is null or undefined then nil is returned.
// If the value is not an object then a JavaScript TypeError will be thrown.
// The property "length" is read from the object, converted to an unsigned
// integer, and an NSArray of this size is allocated. Properties corresponding
// to indicies within the array bounds will be copied to the array, with
// Objective-C objects converted to equivalent JSValues as specified.
- ( NSArray  *)toArray;
 
// If the value is null or undefined then nil is returned.
// If the value is not an object then a JavaScript TypeError will be thrown.
// All enumerable properties of the object are copied to the dictionary, with
// Objective-C objects converted to equivalent JSValues as specified.
- ( NSDictionary  *)toDictionary;

 

Accessing Javascript Code in Objective-C

1).Evaluating Javascript Code

1
2
3
4
NSString  * jsCode = @"1+2" ;
JSContext  *context = [[ JSContext  alloc ]  init ];
JSValue  * value = [context  evaluateScript :jsCode];
NSLog( @"Output = %d" , [value  toInt32 ]);

 

2).Access Javascript Variables. Variables and functions are accessed from JSContext.
To access varible from Javascript : context[@"x"]
To access function from javascript : context[@"myfun"]

1
2
3
4
5
6
JSContext  *context = [[ JSContext  alloc ]  init ];
     NSString  * jsCode = @"var x; x=10;" ;
     [context  evaluateScript :jsCode];
 
     JSValue  * a =context[ @"x" ];
     NSLog( @"x = %d" , [a  toInt32 ]);

 

3).Access Javascript functions and execute them in Objective-C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//function with arguments
     JSContext  *context = [[ JSContext  alloc ]  init ];
     NSString  * jsCode = @"function sum(a,b) { return a+b;} " ;
     [context  evaluateScript :jsCode];
 
     JSValue  * func =context[ @"sum" ];
     NSArray  * args = @[[ NSNumber  numberWithInt : 1 0 ],[ NSNumber  numberWithInt : 2 0 ]];
     JSValue  * ret =[func  callWithArguments :args];
     NSLog( @"10+20 = %d" , [ret  toInt32 ]);
 
     //function without arguments
     NSString  * jsCode 2  = @"function getRandom() { return parseInt(Math.floor((Math.random()*100)+1));} " ;
     [context  evaluateScript :jsCode 2 ];
 
     JSValue  * func 2  =context[ @"getRandom" ];
 
     for ( int  i= 0 ;i< 5 ;i++)
     {
         JSValue  * ret 2  =[func 2  callWithArguments :nil ];
         NSLog( @"Random Value = %d" , [ret 2  toInt32 ]);
     }

 

Call Objective-C code from JavaScript

Objective-C code is called from JavaScript in two ways

1.CODE BLOCKS

Objective-C code block can be called from JavaScript.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
JSContext  *context = [[ JSContext  alloc ]  init ];
 
     //we are telling that "sum" is function, takes two arguments
     context[ @"sum" ] = ^( int  arg 1 , int  arg 2 )
     {
         return  arg 1 +arg 2 ;
     };
 
     NSString  * jsCode = @"sum(4,5);" ;
     JSValue  * sumVal = [context  evaluateScript :jsCode];
 
     NSLog( @"Sum(4,5) = %d" , [sumVal  toInt32 ]);
 
     //we are telling that "getRandom" is function, does not take any arguments
     context[ @"getRandom" ] = ^()
     {
         return  rand()% 1 0 0 ;
     };
 
     NSString  * jsCode 2  = @"getRandom();" ;
     for ( int  i= 0 ;i< 5 ;i++)
     {
         JSValue  * sumVal 2  = [context  evaluateScript :jsCode 2 ];
         NSLog( @"Random Number = %d" , [sumVal 2  toInt32 ]);
     }

 

2.USING JSEXPORT PROTOCOL

You can see the comparison between Objective-C Object and it’s equivalent Javascript Object below.

1
2
3
4
5
6
7
8
9
10
11
12
@interface  MyObject
@property   int  x;
 
-( int ) getX;
+( MyObject  *)  getSqure :(MyObject*)obj;
 
@end
 
//Usage:
MyObject  * obj = [ MyObject  new ];
[obj  getX ];
[ MyObject  getSqure :obj];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function  MyObject()
{
     //member variable
     this .x=0;
 
     //instance method
     this .getX = function ()
                     {
                     return  this .x;
                     }
}
 
//static method
MyObject.getSqure = function (obj)
{
     var  newObj = new  MyObject();
     newObj.x = obj.x * obj.x;
     return  newObj;
}
 
//Usage:
var  obj = new  MyObject();
obj.x=10;
var  sqrObj = MyObject.getSqure(obj);

To make Javascript interacting with Objective-C Object, We need to have a Protocol which should be inherited
from JSExport. Move all the variables and functions to prototype to access them in JavaScript.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@protocol  MyObjectExport
@property   int  x;
 
-( int ) getX;
+( MyObject  *)  getSqure :(MyObject*)obj;
 
@end
 
@interface  MyObject  : NSObject  <MyObjectExport>
 
//this method is not accessible in javascript
-( void ) test;
 
@end ;
 
@implementation  MyObject
@synthesize  x;
 
-( int ) getX
{
     return  self .x ;
}
+( MyObject  *)  getSqure :(MyObject*)obj;
{
     NSLog( @"Calling getSqure" );
     MyObject  * newObj = [ MyObject  new ];
     newObj .x  = obj .x  * obj .x ;
 
     return   newObj;
}

Now MyObject(Objective-C)’s variables and functions are directly accessed from javascript.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
JSContext  * context = [[ JSContext  alloc ]  init ];
NSString  * jsCode = @"function sqrtOf(obj){ return MyObject.getSqure(obj);}" ;
 
     //adding Objective-C Class to Javascript.
     context[ @"MyObject" ]=[ MyObject  class ];
 
     [context  evaluateScript :jsCode];
 
     MyObject  * obj =[ MyObject  new ];
     obj .x  = 1 0 ;
 
     JSValue  * func =context[ @"sqrtOf" ];
     JSValue  * val = [func  callWithArguments :@[obj]];
 
     //we got MyObject from javascript.
     MyObject  *sqrtObj = [val  toObject ];
 
     NSLog( @"Value =%d, %d" , obj .x , [sqrtObj  getX ]);
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值