【笔记】React Native之iOS记录

本文详细介绍了如何解决在React Native项目中遇到的Webview编译问题,通过修改RNCWebView.m文件来适配iOS11以上版本。同时,文章讲解了如何在Objective-C中创建React Native模块,包括异步和同步函数的实现,并给出了具体代码示例。此外,还展示了如何在Objective-C中实现广播消息的发送与接收,以及在React Native中监听并响应这些广播事件。对于广播触发多次的问题,提出了改为页面刷新的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.遇上react-native-webview死活不能编译成功

设置minVersion是iOS11,yarn install一把,然后死活都运行不了,这个时候需要将../node_modules/react-native-webview/apple/RNCWebView.m修改一下

#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */
    _mediaCapturePermissionGrantType = RNCWebViewPermissionGrantType_Prompt;
#endif

2.怎么写传递函数?

@interface后面加RCTBridgeModule,在@implementation下方加RCT_EXPORT_MODULE();

公开的函数大概是:RCT_EXPORT_METHOD(afun:(RCTResponseSenderBlock)callback){}

这是异步callback;还有一种类似同步的写法RCT_EXPORT_METHOD(afun:(NSString*)aStr resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){}

简单的例子:

OC部分:xx.h

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
@interface myModule : NSObject<RCTBridgeModule>
@end

xx.m

#import "xx.h"
@implementation myModule
RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(afun:(RCTResponseSenderBlock)callback)
{
    if(callback)
    {
        NSMutableArray *resp = [NSMutableArray array];
        [resp addObject:@"this is a test."];
        callback(resp);
    }
}

RCT_EXPORT_METHOD(bfun:(NSString *)aStr resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    int flag = rand();
    if(flag>100)
    {
        if(resolve)
        {
            resolve([NSNumber numberWithBool:YES]);
        }
    }
    else
    {
        reject(@"-1",@"error rise",[NSError errorWithDomain:NSCocoaErrorDomain code:-1 userInfo:nil]);
    }
}

@end

在aa.tsx实现:

import { NativeModules} from 'react-native';

const myModule = NativeModules.myModule;

myModule.afun((resp) => {
    console.log(resp);
});

myModule.bfun('this is a test').then(flag => {
    console.log('return='+flag);
}).catch(() => {
    console.log('error');
});

3.怎么写广播消息?

h文件中要继承RCTEventEmitter;在m文件中要实现至少3个固定的函数

- (NSArray<NSString *> *)supportedEvents;

- (void)startObserving;

- (void)stopObserving;

外加接收内部广播的函数- (void) listenGEvent:(NSNotification *)notification;

在其他地方调用发广播,则使用内部的notificationName,参考一下例子。

yy.h

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface myMessage : RCTEventEmitter<RCTBridgeModule>
@end

yy.m

#import "yy.h"
@implementation myMessage
RCT_EXPORT_MODULE();


- (NSArray<NSString *> *)supportedEvents
{
  return @[@"gEventName"];
}


- (void)startObserving
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(listenGEvent:)
                                                 name:@"gEventNotification" 
                                               object:nil];
}
- (void)stopObserving
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void) listenGEvent:(NSNotification *)notification
{
    [self sendEventWithName:@"gEventName" body:notification.object];
}

@end

调用广播:

NSDictionary *info=[NSDictionary dictionaryWithObject:@"aaaa" forKey:@"test"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"gEventNotification" object:info];

bb.tsx的实现监听事件:

import { NativeModules,NativeEventEmitter } from 'react-native';

const myMessage = NativeModules.myMessage;

const myEvents = new NativeEventEmitter(myMessage);


myEvents.addListener('gEventName',(data)=>{
	console.log(data);
	});

2022.02.22补充一下广播的插曲:

App在广播回传状态后,前端会相应提示,很意外的发现同一个广播的消息多次触发,前端没办法屏蔽,最后我建议将alert去掉,改为面页刷新。我猜测和js的addListen事件有关吧,有啥其他想法的可以评论留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值