React Native学习之RN与iOS原生通信
iOS 平台开发语言分为:Objective-C
和Swift
,目前 React Native 只能与Objective-C
代码交互,与Swift
代码交互必须先与Objective-C
交互,再通过Objective-C
与Swift
交互,由于Swift
的某些先进特性,这种方式的混合开发完全是值得的,并不会有性能损失。
#import "RCTBridgeModule.h" //导入这个头文件以现实RCTBridgeModule协议
#import "RCTBridge.h" //导入这个头文件以实现向RN侧发送事件
#import "RCTEventDispatcher.h" //导入这个头文件以实现向RN侧发送事件
ExampleInterface.h
#import <Foundation/Foundation.h>
#import "RCTBridgeModule.h" // 导入这个头文件以现实RCTBridgeModule协议
#import "RCTBridge.h" // 导入这个头文件以实现向RN侧发送事件
#import "RCTEventDispatcher.h" // 导入这个头文件以实现向RN侧发送事件
@interface ExampleInterface : NSObject<RCTBridgeModule>
@property (nonatomic, strong)NSString *contactName; // 保存联系人名字
@property (nonatomic, strong)NSString *contactPhoneNumber; // 保存联系人电话号码
@end
ExampleInterface.m
#import "ExampleInterface.h"
#import "CallAdressbookViewController.h" //这是开发者使用Objective-C开发的类的头文件
@interface ExampleInterface()
@property (nonatomic, strong)NSDictionary *dic;
@end
@implementation ExampleInterface
- (instancetype) init{
return self;
}
- (NSString *)contactName{
if (!_contactName) {
_contactName = @"";
}
return _contactName;
}
@synthesize bridge=_bridge;
// 除了现实RCTBridegModule协议外,类还需要包含RCT_EXPORT_MODELE()宏。这个宏可以添加一个参数用来指定在js中访问这个模块的名字
// 通常不指定名字,默认使用Objective-C类的名字
RCT_EXPORT_MODULE();
// 使用RCT_EXPORT_METHOD()宏声明需要提供给RN组件调用的方法
RCT_EXPORT_METHOD(sendMessage: (NSString *)msg)
{
// 在调试窗口中打印React Native调用此函数时携带的参数
NSLog(@"收到的来自React Native的消息:%@", msg);
// 检测收到的消息是否为json格式
NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
if (error != nil) {
NSLog(@"解析错误:%@", error);
} else {
// 没有错误则通知React Native,发送消息给React Native
[self.bridge.eventDispatcher sendAppEventWithName:@"NativeModuleMsg" body:@{@"message":@"发送消息通知React Native - 没有解析错误"}];
}
// 检测消息的msgType是否为pickContact,如果是则初始化挑选联系人界面
NSString *login = [dic objectForKey:@"msgType"];
if ([login isEqualToString:@"pickContact"]) [self callAddress];
}
- (void)callAddress {
UIViewController *controller = (UIViewController*)[[[UIApplication sharedApplication]keyWindow] rootViewController];
CallAdressbookViewController *addressbookViewController = [[CallAdressbookViewController alloc] init];
[controller presentViewController:addressbookViewController animated:YES completion:nil];
self.contactName = addressbookViewController.contactName;
self.contactPhoneNumber = addressbookViewController.contactPhoneNumber;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(calendarEventReminderReceived:) name:@"Num" object:nil];
}
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
- (void)calendarEventReminderReceived:(NSNotification *)notification{
self.contactPhoneNumber = notification.object;
self.contactName = notification.userInfo[@"name"];
// 去除获取到的电话号码中的特殊字符
self.contactPhoneNumber=[self.contactPhoneNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
self.contactPhoneNumber = [self.contactPhoneNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
self.contactPhoneNumber = [self.contactPhoneNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
self.contactPhoneNumber = [self.contactPhoneNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
[dic setObject:@"pickContactResult" forKey:@"msgType"];
if(self.contactPhoneNumber==nil){
self.contactPhoneNumber=@"";
}
[dic setObject:self.contactPhoneNumber forKey:@"peerNumber"];
if(self.contactName == nil){
self.contactName = @"";
}
// 组装发送给rn侧的消息
[dic setObject:self.contactName forKey:@"displayName"];
self.dic = [dic copy];
NSError *error = [[NSError alloc] init];
NSData *data = [NSJSONSerialization dataWithJSONObject:self.dic options:0 error:&error];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// 向React Native发送消息
[self.bridge.eventDispatcher sendAppEventWithName:@"NativeModuleMsg" body:@{@"message":str}];
}
@end
CallAdressbookViewController.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface CallAdressbookViewController : UIViewController
@property (nonatomic, strong)NSString *contactName;
@property (nonatomic, strong)NSString *contactPhoneNumber;
@end
CallAdressbookViewController.m
#import "CallAdressbookViewController.h"
#import <AddressBookUI/AddressBookUI.h>
#import <AddressBook/AddressBook.h>
#import "AppDelegate.h"
@class CallAdressbookViewController;
@interface CallAdressbookViewController()<ABPeoplePickerNavigationControllerDelegate>
@end
@implementation CallAdressbookViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
ABPeoplePickerNavigationController *peoplePicker = [[ABPeoplePickerNavigationController alloc] init];
peoplePicker.peoplePickerDelegate = self;
[self presentViewController:peoplePicker animated:YES completion:nil];
[self authoriy];
}
// 授权注册
- (void)authoriy {
// 检查是否是iOS6
if (&ABAddressBookRequestAccessWithCompletion != NULL) {
// iOS6版本中
ABAddressBookRef abRef = ABAddressBookCreateWithOptions(NULL, NULL);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
// 如果从未申请过权限,申请权限
ABAddressBookRequestAccessWithCompletion(abRef, ^(bool granted, CFErrorRef error) {
// 根据granted参数判断用户是否同意授予权限、
if (granted) {
// 查询所有,即显示通讯录所有联系人
[self getContacts];
}
});
} else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
// 如果权限已经被授予,查询所有,即显示通讯录所有联系人
[self getContacts];
} else {
// 如果权限被收回,提醒用户去系统设置菜单中打开
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:@"请您设置允许APP访问您的通讯录\n设置>通用>访问权限" delegate:self cancelButtonTitle:@"" otherButtonTitles:nil, nil];
[alert show];
return;
}
if (abRef) {
CFRelease(abRef);
}
}
}
// 获取全部通讯录单元信息
- (void)getContacts {
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
// 1.取全部联系人
CFArrayRef allPerson = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex number = ABAddressBookGetPersonCount(addressBook);
// 进行遍历
for (NSInteger i = 0; i < number; i ++) {
ABRecordRef people = CFArrayGetValueAtIndex(allPerson, i);
// 2.获取联系人的姓名
NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));
NSString *middleName = (__bridge NSString *)(ABRecordCopyValue(people, kABPersonMiddleNameProperty));
NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty));
NSString *nameString = nil;
if (firstName.length != 0) nameString = firstName;
if (middleName.length != 0) nameString = [nameString stringByAppendingString:middleName];
if (lastName.length != 0) nameString = [nameString stringByAppendingString:lastName];
// if (firstName.length == 0 || lastName.length == 0) nameString = firstName ? [NSString stringWithFormat:@"%@%@" , firstName(lastName ? lastName : @"") ] : @"";
// nameString = middleName.length ? [NSString stringWithFormat:@"%@%@%@", lastName, middleName, firstName] : [NSString stringWithFormat:@"%@%@", lastName, firstName];
NSLog(@"姓名:%@", nameString);
// 3.获取联系人的头像图片
// NSData *userImageData = (__bridge NSData *)(ABPersonCopyImageData(people));
// UIImage *userImage = [UIImage imageWithData:userImageData];
// NSData *data = UIImageJPEGRepresentation(userImage, 1.0);
// NSString *userImageString= [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
// NSURL *userImageURL = [NSURL URLWithString:userImageString];
// NSLog(@"头像:%@", userImageURL);
// 4.获取联系人电话
ABMutableMultiValueRef phoneMutil = ABRecordCopyValue(people, kABPersonPhoneProperty);
NSMutableArray *phones = [[NSMutableArray alloc] init];
for (int i = 0; i < ABMultiValueGetCount(phoneMutil); i ++) {
// NSString *phone = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(phoneMutil, i));
NSString *phoneLabel = (__bridge NSString *)(ABMultiValueCopyLabelAtIndex(phoneMutil, i));
// if (phone.length < 11) {
// break;
// }
if ([phoneLabel isEqualToString:@"_$!<Mobile>!$_"]) {
[phones addObject:(__bridge id _Nonnull)(ABMultiValueCopyValueAtIndex(phoneMutil, i))];
} else {
[phones addObject:(__bridge id _Nonnull)(ABMultiValueCopyValueAtIndex(phoneMutil, i))];
}
}
for (int i = 0; i < phones.count; i ++) {
NSLog(@"电话%d:%@", i+1, phones[i]);
}
}
}
#pragma mark - ABPeoplePickerNavigationControllerDelegate
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
ABMultiValueRef valuesRef = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex index = ABMultiValueGetIndexForIdentifier(valuesRef, identifier);
CFStringRef value = ABMultiValueCopyValueAtIndex(valuesRef, index);
// 获取联系人姓名
// ABRecordRef people = CFArrayGetValueAtIndex(valuesRef, index);
// NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(people, kABPersonFirstNameProperty));
// NSString *middleName = (__bridge NSString *)(ABRecordCopyValue(people, kABPersonMiddleNameProperty));
// NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(people, kABPersonLastNameProperty));
// NSString *nameString = nil;
// if (firstName.length != 0) nameString = firstName;
// if (middleName.length != 0) nameString = [nameString stringByAppendingString:middleName];
// if (lastName.length != 0) nameString = [nameString stringByAppendingString:lastName];
// if (firstName.length == 0 || lastName.length == 0) nameString = firstName ? [NSString stringWithFormat:@"%@%@" , firstName(lastName ? lastName : @"") ] : @"";
// nameString = middleName.length ? [NSString stringWithFormat:@"%@%@%@", lastName, middleName, firstName] : [NSString stringWithFormat:@"%@%@", lastName, firstName];
CFStringRef anFullName = ABRecordCopyCompositeName(person);
[peoplePicker dismissViewControllerAnimated:YES completion:^{
[self dismissViewControllerAnimated:YES completion:^{
self.contactPhoneNumber = (__bridge NSString *)(value);
self.contactName = (__bridge NSString *)(anFullName);
[[NSNotificationCenter defaultCenter] postNotificationName:@"Num" object:self.contactPhoneNumber userInfo: @{@"name" : self.contactName}];
NSLog(@"%@ %@", self.contactPhoneNumber, self.contactName);
}];
}];
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {
[peoplePicker dismissViewControllerAnimated:YES completion:^ {
// 获取联系人姓名
// NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonFirstNameProperty));
// NSString *middleName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonMiddleNameProperty));
// NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(person, kABPersonLastNameProperty));
// NSString *nameString = nil;
// if (firstName.length != 0) nameString = firstName;
// if (middleName.length != 0) nameString = [nameString stringByAppendingString:middleName];
// if (lastName.length != 0) nameString = [nameString stringByAppendingString:lastName];
// if (firstName.length == 0 || lastName.length == 0) nameString = firstName ? [NSString stringWithFormat:@"%@%@" , firstName(lastName ? lastName : @"") ] : @"";
// nameString = middleName.length ? [NSString stringWithFormat:@"%@%@%@", lastName, middleName, firstName] : [NSString stringWithFormat:@"%@%@", lastName, firstName];
CFStringRef anFullName = ABRecordCopyCompositeName(person);
[self dismissViewControllerAnimated:YES completion:^{
ABMultiValueRef phones = ABRecordCopyValue(person,kABPersonPhoneProperty);
NSString *phone = nil;
for (int i = 0; i < ABMultiValueGetCount(phones); i++) {
phone = (__bridge NSString *)(ABMultiValueCopyValueAtIndex(phones, i));
NSLog(@"telephone = %@",phone);
}
self.contactPhoneNumber = phone;
self.contactName = (__bridge NSString *)(anFullName);
[[NSNotificationCenter defaultCenter] postNotificationName:@"Num" object:self.contactPhoneNumber userInfo: @{@"name" : self.contactName}];
NSLog(@"%@ %@", self.contactPhoneNumber, self.contactName);
}];
}];
return YES;
}
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{
[self dismissViewControllerAnimated:YES completion:^{
[self dismissViewControllerAnimated:YES completion:nil];
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/react-native-learning-for-rn-and-ios-native-communication/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
THE END
0
二维码
打赏
海报
React Native学习之RN与iOS原生通信
iOS 平台开发语言分为:Objective-C和Swift,目前 React Native 只能与Objective-C代码交互,与Swift代码交互必须先与Objective-C交互,再通过Objective-C与Sw……
文章目录
关闭
共有 0 条评论