React Native-iOS Nativeフィードバック

5533 ワード

(Native方法はiOS/Android原生コードと解釈する)実際の使用シーンでは、Nativeを呼び出した方法だけでなく、結果を処理する必要があります.Native処理が終わったら戻ります.また、JavaScriptで操作と処理を行います.このようにJavaScriptのコールバック関数を使って結果を処理する必要があります.React NativeにおいてObject-cは、RCTReponseSenderBlockPromisesの2つの方式のフィードバックがある.
1.RCTReponsenderBlock
JavaScriptとObject-Cのパラメータリストには、RCTReponseSenderBlockがJavaScriptに対応するFunctというパラメータがあります.これはJavaScriptがObject-Cを呼び出すCallbackです.RCTReponseSenderBlockRCTBridgeModule.hにおいて定義されたblockであり、完全な定義:
typedef void (^RCTResponseSenderBlock)(NSArray *response);
RCTReponseSenderBlockはObject-C Bridgeの動作を定義し、JavaScriptにcalbackを返す方法です.
彼のパラメータはNSArrayです.最初のパラメータはerrorであり、エラーがなければnullに入力され、後のパラメータはカスタムコンテンツに入力される.具体例:まずUIAlertViewに2つのボタンを追加し、ボタンをクリックした後、RCTResponseSenderBlockを使ってJavaScriptに戻ります.まず、UIAlertViewDelegateを実現する.
@interface RNIOSAlert : NSObject
@end
変数を定義してパラメータを保存します.
@implementation RNIOSAlert{
  RCTResponseSenderBlock _alertCallback;
}
@end
clickedButotonAtIndex方法で結果を処理し、コールバック関数を呼び出します.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    switch (alertView.tag) {
        case 0:
            if (buttonIndex == 0) {
                _alertCallback(@[@"  "]);
            }else{
                _alertCallback(@[[NSNull null],@"  "]);
            }
            break;
        default:
            break;
    }
}
最後にチューニングパラメータを持つNative方法を定義します.
RCT_EXPORT_METHOD(showAlertViewAndMsg:(NSString *)message Callback:(RCTResponseSenderBlock) alertCallback){
    _alertCallback = alertCallback;
    dispatch_sync(dispatch_get_main_queue(), ^{
        UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"React Native" message:message delegate:self cancelButtonTitle:@"  " otherButtonTitles:@"  ", nil];
        alert.tag = 0;
        [alert show];
    });
}
JavaScriptでNative方法を呼び出し、フィードバックを処理する:
_alertCallback() {
    RNIOSAlert.showAlertAndCallback(function (err, datas) {
        if (err) {
            console.warn('err', '   ');
        } else {
            console.warn('data', '   ');
        }
    });
}
UALertViewを閉じるたびに、JavaScript処理の結果が見られます.
2.Promises
PromisesはES6における特性であり、JavaScriptに対して非同期的なプログラミングインターフェースを提供することを目的として、Callback地獄を回避し、Callbackの階層的な入れ子を解決した.非同期動作をより容易に制御する.React Native-PromiseオブジェクトはReact NativeにおいてPromisesに対して完璧なサポートがあり、Object-CのNativeメソッドを呼び出したときに、Object-CからJavaScriptにコードを実行させることもできます.まずPromisesの二つの状態を見ます.
ResoveとRejectはPromiseの二つの状態です.解決したと拒否したと表しています.
  • Resoliveは解決された実行結果であり、then動作をトリガする
  • .
  • Rejectは拒否された実行結果であり、Object-Cでのcatch動作をトリガするのは、RCTPromiseResolveBlock及びRCTPromiseRejectBlockであり、両方とも定義されたObject-C bridgeである.
  • RCTPromiseResolveBlockの実装:
    typedef void (^RCTPromiseResolveBlock)(id result);
    
    IDをパラメータとして、当然ながらパラメータはObject-cとJavaScriptで定義されているパラメータでなければなりません.RCTPromiseRejectBlockの実装:
    typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error);
    
    RCTPromiseRejectBlockはNSErrorを使用しており、カスタムのコードやメッセージを入力することもできます.
     NSError * error =[NSError errorWithDomain:@"test" code:0 userInfo:nil];
    
    Promiseを使ってリプライを実現
    まず2つの変数を定義してパラメータを保存します.
    @implementation RNIOSAlert{
        RCTPromiseResolveBlock _resolveBlock;
        RCTPromiseRejectBlock _rejectBlock;
    }
    
    JavaScriptに提供するNative関数を定義します.
    
    RCT_REMAP_METHOD(alertUsePromise,resolve:(RCTPromiseResolveBlock)resolve
                     reject:(RCTPromiseRejectBlock)reject){
        _resolveBlock = resolve;
        _rejectBlock = reject;
        
        dispatch_sync(dispatch_get_main_queue(), ^{
            UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"React Native " message:@"  Promise     alertUsePromise" delegate:self cancelButtonTitle:@"  " otherButtonTitles:@"  ", nil];
            alert.tag = 1;
            [alert show];
        });
    }
    
    ここではRCT_REMAP_METHODマクロを用いてNativeを定義し、彼の最初のパラメータは方法名であり、後のパラメータは方法の実現であり、JavaScriptがPromiseを呼び出したときに方法名に反映される必要はない.結果を処理し、コールバックを使用します.
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
        if (buttonIndex == 0) {
            NSError * err=[NSError errorWithDomain:@"test" code:0 userInfo:nil];
            _rejectBlock(@"0",@"cancel",err);
        }else{
            _resolveBlock(@[@"  "]);
        }
    }
    
    JavaScriptでこの方法を呼び出します.
    _alertUsePromise() {
         RNIOSAlert.alertUserPromise().then((datas)=> {
             console.warn('data', datas);
         }).catch((err)=> {
             console.warn('err', err);
         });
     }
    
    ここのthenはResovale状態の結果を処理し、catchはReject状態の結果を処理する.async/awaitを使ってもいいです.
    async  _alertPromise() {
         try {
             var datas = await RNIOSAlert.alertUserPromise();
             console.warn('data', datas);
         } catch (e) {
             console.warn('err', e);
         }
     }
    
    async/awaitは2つのキーワードであり、Promisesの思想を言語そのものに組み込むために用いられる.彼らはもうcatchのような擬似同期のコードを書く必要がなくて、直接try/catch/returnのようなキーワードを使えばいいです.Promisesは回調の使用に便利です.できるだけJavaScriptの反転地獄を避けます.