前提条件まず、ocの文法について少し理解しておくのがベストです。 1. 宣言ファイルnativeModule.hを作成する #import <Foundation/Foundation.h> #import <React/RCTBridgeModule.h> @interface ネイティブモジュール: NSObject <RCTBridgeModule> @終わり 2. nativeModule.mファイルを作成する #import <Foundation/Foundation.h> #"nativeModule.h"をインポートします @interface ネイティブモジュール () @終わり @実装ネイティブモジュール @終わり これはファイルを追加した後のディレクトリ構造です。 インターフェースの違いについて: .h 内の @interface は他のクラスが呼び出すために使用されます。 @property と関数は他のクラスから「見える」 (public) .m 内の @interface は OC ではクラス拡張と呼ばれ、.h ファイルの @interface を補足するものです。ただし、.m ファイル内の @interface は外部に公開されておらず、.m ファイル内でのみ表示されます (プライベート) そのため、外部に公開するメソッドと変数は .h ファイルに配置し、外部に公開したくない変数は .m ファイルに配置します (.m ファイル内のメソッドは宣言なしで直接使用できます)。 RNはiOSに価値を渡す方法1: ネイティブに通常通り値を渡す.m ファイルに次のメソッドを追加します。 //上記のコードを省略 @implementation nativeModule // このコードは、nativeModule モジュールが RN でアクセスできるようにモジュールをエクスポートするために必要です。 RCT_EXPORT_MODULE(); // 文字列を受け取る RCT_EXPORT_METHOD(addHelloWord:(NSString *)name location:(NSString *)location) { NSLog(@"%@,%@", 名前、場所); } @終わり RNコード: 'react-native' から { Button, NativeModules } をインポートします。 const { nativeModule } = ネイティブモジュール <Button title={'2つのパラメータをネイティブに渡す'} onPress={() => { nativeModule.addHelloWord('あなたの名前', '場所: 浙江省') }}/> このボタンをクリックすると、「your name」と「location: Zhejiang」の 2 つの文字列がネイティブ側に渡されます。 方法2: コールバック関数を渡す.m ファイルに追加します: // 1 つのパラメータ(JavaScript コールバック関数に渡されるパラメータの配列)のみを受け入れます。 RCT_EXPORT_METHOD(checkIsRoot:(RCTResponseSenderBlock)コールバック) { NSArray *配列 = @[@"文字列", @"数値"]; コールバック(配列); } RN にコードを追加します: <Button title={'js はネイティブにコールバックを渡し、コールバックで配列を受け取ります'} onPress={() => { nativeModule.checkIsRoot((str: 文字列, num: 文字列) => { コンソール.log(文字列、数値) }) }}/> これは、いくつかの操作が完了した後にコールバックを解決するために RN のネイティブ エンドに渡されるコールバック関数です。**コールバックが複数回呼び出されると、RN はエラーを報告します** 方法3: プロミスコールバックを取得する.m ファイルに次のコードを追加します。 @interface ネイティブモジュール () @property (非アトミック) RCTPromiseResolveBlock normalResolve; @property (非アトミック) RCTPromiseRejectBlock normalReject; @property (非アトミック) NSInteger num; @終わり // これはタイマーです - (void)startTime: (NSArray*) data{ NSTimer *timer = [NSTimer schedulingTimerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) { NSArray *events =@[@"Promise ",@"test ",@" 配列"]; if (イベント) { イベントを通常の状態に戻します。 [タイマー無効化]; } それ以外 { [タイマー無効化]; NSError *error=[NSError errorWithDomain:@"エラーメッセージを呼び出しています..." code:101 userInfo:nil]; self.normalReject(@"no_events", @"イベントはありませんでした", error); } }]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; } // RNへのコールバックパラメータ、コールバックエラー情報 RCT_EXPORT_METHOD(getHBDeviceUniqueID: (RCTPromiseResolveBlock)resolve 拒否者:(RCTPromiseRejectBlock)拒否) { // 実行されるタスク self.normalResolve = resolve; 自己.normalReject = 拒否; [self performSelectorOnMainThread:@selector(startTime:) withObject: [NSArray arrayWithObjects: @"1", @"2", nil] waitUntilDone:YES]; } RN にコードを追加します: <Button title={'ネイティブはPromiseをJSに渡します'} onPress={() => { nativeModule.getHBDeviceUniqueID().then((arr: string[]) => { console.log('解決', arr) }).catch((err: 文字列) => { コンソール.エラー(err) }) }}/> nativeModule.getHBDeviceUniqueID の実行は、ネイティブ側のコールバックを取得できる Promise であり、実際には方法 2 に似ています。 方法4: 同期的にpromiseを取得する方法.m ファイルに追加します: // これはタイマー2です -(void)startTime2: (NSArray*) データ{ NSLog(@"データ%@",データ); NSTimer *timer = [NSTimer schedulingTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) { NSLog(@"%d", (int)self.num); 自己番号 = 自己番号 + 1; NSLog(@"%d", (int)self.num); (自己番号>4)の場合{ [タイマー無効化]; NSLog(@"終了"); データを通常の状態に戻します。 } }]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; } // RCT_REMAP_METHOD は RCT_EXPORT_METHOD と同じですが、このメソッドは JS スレッド上の JS から同期的に呼び出され、結果を返す場合があります。 // 同期にはパフォーマンス上の問題が生じる可能性があります。RCT_REMAP_METHOD(findEvents, を使用しないことをお勧めします。 findEventsWithResolver:(RCTPromiseResolveBlock) 解決する 拒否者:(RCTPromiseRejectBlock)拒否) { 自己解決を通常の方法で解決します。 自己.normalReject = 拒否; 自己番号 = 0; [self performSelectorOnMainThread:@selector(startTime2:) withObject: [NSArray arrayWithObjects: @"1", @"2", nil] waitUntilDone:YES]; } RN 側にコードを追加します。 <Button title={'ネイティブは JS2 に Promise を渡します'} onPress={() => { nativeModule.findEvents().then((arr: string[]) => { console.log('解決', arr) }).catch((err: 文字列) => { コンソール.エラー(err) }) }}/> 方法 4 は基本的に方法 3 と同じですが、違いが 1 つあります。それは、RCT_REMAP_METHOD がこの方法を使用してコードを同期状態にすることです。 iOSはRNエンドに値を渡す初期データ提供appDelegate.m に次のコードを追加します。 NSArray *imageList = @[@"http://foo.com/bar1.png", @"http://foo.com/bar2.png"]; NSDictionary *props = @{@"images" : imageList}; RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"learn" initialProperties:props]; // このコード行はすでに存在します。違いは initialProperties:props です。 RN 側に次のように記入します: // APP を書き換えます。images は iOS によって提供されるデータです。ここではコンテキストを通じてデータを渡します。export default class App extends React.Component<{ images: string[] }> { 与える() { <NativeProps.Provider 値 = {this.props.images}> を返します。 <AppContainer/> </ネイティブプロパティ.プロバイダー> } } // フックで使用するだけです const images = useContext(NativeProps); <Text>これはネイティブ側からの初期データです {JSON.stringify(images)}</Text> イベントリスナーの追加.m ファイルに次のコードを追加します。 // 監視可能なイベント名 - (NSArray<NSString *> *)supportedEvents { @[@"EventReminder"] を返します。 } RCT_EXPORT_METHOD(postNotificationEvent:(NSString *)名前) { NSLog(@"カレンダーイベントリマインダーを受信しました"); [self sendEventWithName:@"EventReminder" 本文:@{@"name": name}];; } - (void)calendarEventReminderReceived:(NSNotification *)通知 { // これは公式ウェブサイトからの例です NSLog(@"calendarEventReminderReceived"); NSString *eventName = notification.userInfo[@"name"]; [self sendEventWithName:@"EventReminder" 本文:@{@"name": eventName}]; } RCT_EXPORT_METHOD(送信){ NSDictionary *dict = @{@"name" : @"veuimyzi"}; NSNotification *notification = [[NSNotification alloc] initWithName:@"EventReminder" object:nil userInfo:dict]; [自己カレンダーイベントリマインダー受信:通知]; } RN にコードを追加します: const ManagerEmitter = 新しい NativeEventEmitter(nativeModule) 定数[メッセージ、setMsg] = useState([]) // フック内で使用。componentDidMount ライフサイクルに似ている。useEffect(() => { const サブスクリプション = ManagerEmitter.addListener( 「イベントリマインダー」、 (リマインダー)=> { setMsg(前の状態 => { prevState.concat(リマインダー.name) を返します }) console.log('これは監視されたEventReminderイベント応答です', reminder.name) } ) 戻り値 () => { サブスクリプション.削除() } }, []) <Button title={'js はイベントをリッスンし、ネイティブが js に通知を送信できるようにします'} onPress={() => { ネイティブモジュールの postNotificationEvent('テスト') }}/> <Button title={'js はイベントをリッスンし、ネイティブが js に通知を送信できるようにします'} onPress={() => { ネイティブモジュール.Send() }}/> { msg.map((項目, インデックス) => { <テキストキー={item + index}>item:{item}</Text>を返します }) } postNotificationEvent メソッドは最も簡単に使用できます。ネイティブ側で sendEventWithName を呼び出すと、RN リスナーにデータを渡すことができます。 もう 1 つの方法は Send と calendarEventReminderReceived です。1 つは公式 Web サイトからのものです。この例では NSNotification からデータを取得し、Send はデータを calendarEventReminderReceived に渡します。 監視の最適化に関しては、公式サイトにもリンクがあります。時間があるときに見てみてください。.m ファイルに次のコードを追加するだけです。 @実装ネイティブモジュール { bool リスナーがあります。 // ローカル変数 } -(void)観察開始{ リスナーあり = YES; } -(void)観察を停止{ リスナーあり = NO; } // リスナーを送信するときに判断を追加します。リスナーがある場合にのみ送信し、ブリッジコードの呼び出しを効果的に削減します。if (hasListeners) { [self sendEventWithName:@"EventReminder" 本文:@{@"name": name}];; } 要約する上記コードのリポジトリ: https://github.com/Grewer/learn-rn ネイティブ側とRN側のやりとりについては、基本的には以上です。もちろん、ネイティブ側でもプロセスなど、より複雑な操作は増えていきます。ブリッジメソッドを書こうとすると、これにたくさん遭遇するでしょう。しかし、上記をマスターすれば、いくつかのサードパーティSDKを呼び出すのに十分です。 以上がReact NativeとIOSの連携についての詳しい説明です。React NativeとIOSの連携についてさらに詳しく知りたい方は、123WORDPRESS.COMの関連記事もぜひご覧ください! 以下もご興味があるかもしれません:
|
<<: Dockerリポジトリの一般的なコマンドの詳細な説明
>>: CentOS6.5 でファイル共有サービス Samba を構築するチュートリアル
目次1. LAN内のプロキシ2. イントラネットの浸透イントラネット侵入とは何ですか?橋プロキシサー...
この記事では、参考までにMySQL zipファイルをインストールする具体的な方法を紹介します。具体的...
mysql の権限とインデックスmysql の最高権限ユーザーは root です。 CREATE U...
データベースはさておき、人生における方言とは何でしょうか?方言とは、ある場所特有の言語です。他の場所...
一緒に学びましょう1. 伝統的な方法コードをコピーコードは次のとおりです。 <object c...
序文MySQL は最も人気のあるリレーショナル データベース管理システムです。WEB アプリケーショ...
オールラウンドなシステム監視ツール dstat dstat は、vmstat、iostat、nets...
1. 親コンポーネントは props を使用して子コンポーネントにデータを渡すことができます。 2....
目次1. Dockerファイル2. pom 構成3. イメージプッシュ4. k8s デプロイメント前...
多くの場合、画像を表示する<a>タグのスタイルに遭遇しますが、タグ内にテキストがあり、そ...
Nexus は RestApi を提供していますが、一部の API はまだ Groovy と組み合わ...
今日、slave_exec_modeというパラメータを偶然見ました。マニュアルの説明から、このパラメ...
目次序文No.1 焦点No.2 複雑な状態ロジックの抽出No.3 複数状態操作の抽出要約する序文Re...
目次1. JavaScriptの基礎2. 基本的なJavaScript構文3. JavaScript...
Docker には多くのログ プラグインがあります。デフォルトでは json-file を使用します...