JavaScriptCore使用案例及Native與JavaScript交互之內部結構剖析

  1. JSVirtualMachine
    JavaScript代碼是在創(chuàng)建JSVirtualMachine類的虛擬機下執(zhí)行,不能在兩個不同JSVirtualMachine類之間進行數(shù)據(jù)傳輸,每個JSVirtualMachine類實例有自己的堆和垃圾回收器.

  2. JSContext
    一個JSContext對象代表一個JavaScript代碼執(zhí)行環(huán)境,是一個全局對象,它在web開發(fā)中等同于一個window對象,同一個JSVirtualMachine類下不同的JSContext之間可以自由傳值疯淫。

  3. JSValue

    是一個主要的數(shù)據(jù)類型,能夠代表任何可能的JavaScript的值,一個JSValue的實例綁定到它所在的JSContext對象中正塌。
    jscore01.png
  4. JSExport

    一種協(xié)議提供了聲明式的方法去向JavaScript代碼導出Objective-C的實例類及其實例方法,類方法和屬性
    jscore02.gif
    第一步請求JavaScript網(wǎng)絡數(shù)據(jù)解析并轉換為Objective-C中對象模型數(shù)組:
    //懶加載JSContext
-(JSContext *)context{
    
    if (_context == nil) {
        
        _context = [[JSContext alloc] init];
        
      NSString *commonJSPath=[[NSBundle mainBundle] pathForResource:@"common" ofType:@"js"];
      NSString *additionsJSPath=[[NSBundle mainBundle] pathForResource:@"additions" ofType:@"js"];
    
      NSString *commomStr=[NSString stringWithContentsOfFile:commonJSPath encoding:NSUTF8StringEncoding error:nil];
    
      NSString *additionsStr=[NSString stringWithContentsOfFile:additionsJSPath encoding:NSUTF8StringEncoding error:nil];
        
        //將OC中的Movie類對象和JavaScript中的Movie對象橋接在一起
        [_context setObject:[Movie self] forKeyedSubscript:@"Movie"];
        
        //執(zhí)行js代碼
        [_context evaluateScript:commomStr];
        [_context evaluateScript:additionsStr];
    }
    
    return _context;
}

-(void)loadMoviesWith:(double)limit  moviesBlock:(void(^)(NSArray *movies))moviesBlock
{
    AFHTTPSessionManager *mgr=[AFHTTPSessionManager manager];
    
    NSURLSessionDataTask *dataTask=[mgr GET:MovieURL parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
      
     NSString *jsonString=[self switchObjectToJSON:responseObject];
      
      //解析JSON數(shù)據(jù)并傳出Movie模型數(shù)組
      moviesBlock([self parseResponseObject:jsonString limit:limit]);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        NSLog(@"MovieViewData Load Error %@",error);
    }];
    
    [dataTask resume];   
}

//解析JSON數(shù)據(jù)
-(NSArray *)parseResponseObject:(NSString *)response limit:(double)limit{
    
    //1
   JSValue *parseFunction=[self.context objectForKeyedSubscript:@"parseJson"];
   NSArray *parsed=[[parseFunction callWithArguments:@[response]] toArray];
    
    //2
   JSValue *filterFunction=[self.context objectForKeyedSubscript:@"filterByLimit"];
   NSArray *filtered=[filterFunction callWithArguments:@[parsed,@(limit)]].toArray;
    
    //3
    return [self switchDictionaryArrayToModelArrayWith:filtered];
}

第二步自定義cell中數(shù)據(jù)設置:

    -(void)setMovie:(Movie *)movie
{
    _movie=movie;
    _nameLabel.text=movie.title;
    _priceLabel.text=movie.price;
    [_imageView sd_setImageWithURL:[NSURL URLWithString:movie.imageUrl]];
}

第三部在控制器調用并加載數(shù)據(jù):

-(NSArray *)movies
{
    if (_movies == nil) {
        
        _movies=[[NSArray alloc] init];
    }
    return _movies;
}
#pragma mark -- UITextFieldDelegate

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    //調用此方法 觸發(fā)textFieldDidEndEditing:方法調用
    [textField resignFirstResponder];
    return YES;
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
    double number=[textField.text doubleValue];
    MovieViewData *mvData= [[MovieViewData alloc] init];

    [mvData loadMoviesWith:number moviesBlock:^(NSArray *movies) {
        self.movies=movies;
        [self.collectionView reloadData];
    }];
}
#pragma mark -- UICollectionViewDataSource

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.movies.count;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
   MovieViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:MovieViewCellID forIndexPath:indexPath]; 
    cell.movie=self.movies[indexPath.row];
    return cell;
}

原生應用與JavaScript交互之內部結構剖析:
jscore03.png
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市燥撞,隨后出現(xiàn)的幾起案子戚扳,更是在濱河造成了極大的恐慌纬乍,老刑警劉巖折联,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棍好,死亡現(xiàn)場離奇詭異棕叫,居然都是意外死亡林螃,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門俺泣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疗认,“玉大人,你說我怎么就攤上這事伏钠『崧” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵熟掂,是天一觀的道長缎浇。 經(jīng)常有香客問我,道長赴肚,這世上最難降的妖魔是什么素跺? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮誉券,結果婚禮上指厌,老公的妹妹穿的比我還像新娘。我一直安慰自己踊跟,他們只是感情好踩验,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著商玫,像睡著了一般箕憾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拳昌,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天袭异,我揣著相機與錄音,去河邊找鬼地回。 笑死扁远,一個胖子當著我的面吹牛俊鱼,可吹牛的內容都是我干的。 我是一名探鬼主播畅买,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼并闲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谷羞?” 一聲冷哼從身側響起帝火,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎湃缎,沒想到半個月后犀填,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡嗓违,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年九巡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹂季。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡冕广,死狀恐怖,靈堂內的尸體忽然破棺而出偿洁,到底是詐尸還是另有隱情撒汉,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布涕滋,位于F島的核電站睬辐,受9級特大地震影響,放射性物質發(fā)生泄漏宾肺。R本人自食惡果不足惜溯饵,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望爱榕。 院中可真熱鬧瓣喊,春花似錦、人聲如沸黔酥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跪者。三九已至棵帽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渣玲,已是汗流浹背逗概。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留忘衍,地道東北人逾苫。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓卿城,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铅搓。 傳聞我的和親對象是個殘疾皇子瑟押,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內容