sundaysgarden

本文已 ReactNative 集成 NIM_iOS_Demo_v4.2.0 为例。Xcode版本为9.0
本人是在已有的ReactNative(以下简称RN)工程下集成云信IM(其他各版本集成方式大同小异)

1. 使用 cocoapods 来安装网易云信依赖

1.首先在 terminal 里进入到自己RN项目ios目录下, 运行 pod init ,(如果电脑没安装cocoapods的,请先安装 cocoapods ),运行完成后,会在当前所在目录下生成 Podfile 文件。

  1. 下载云信 IM demo 源码
    前往 网易云信 下载iOS版 云信IM demo

2. 在 Podfile 里添加网易云信的依赖

  1. terminal 进入到 RN ios目录下执行 pod init,执行后在 ios 目录下生成 Podfile 文件。

  2. 在下载好的云信demo里 NIMDemo 目录下找到 Podfile 文件,复制文件里面的内容到自己的 Podfile 文件里。此部完成后的结果如下

source \'https://github.com/CocoaPods/Specs.git\'
platform :ios, \'9.0\'
# Mall为 RN 工程名字
workspace \'Mall.xcworkspace\'

target \'Mall\' do
  pod \'yoga\', :path => \'../node_modules/react-native/ReactCommon/yoga\'
  pod \'React\', :path => \'../node_modules/react-native\'
  pod \'SDWebImage\', \'4.0.0\'
  pod \'Toast\', \'~> 3.1.0\'
  pod \'M80AttributedLabel\', \'~> 1.6.3\'
  pod \'TZImagePickerController\', \'~> 1.9.0\'
  pod \'FMDB\', \'~> 2.7.2\'
  pod \'Reachability\', \'~> 3.2\'
  pod \'CocoaLumberjack\', \'~> 3.2.1\'
  pod \'SSZipArchive\', \'~> 1.8.1\'
  pod \'SVProgressHUD\', \'~> 2.0.3\'
  # 网易云信的 NIMKit 包
  pod \'NIMKit/Full\', \'~> 1.9.1\'
end

此处和源码里的podfile内容有点不一致,如果不太清楚各项配置的意思,按照我的配置来就行了。

  1. 添加完成后在 terminal 窗口里(Podfile 目录中)执行 pod install,执行完成后会在 ios 目录下生成对应的 Mall.xcworkspace 文件,以后使用Xcode打开项目就是双击此文件即可。

3. 拷贝IM源码到RN里

  • 将demo中的 NIMDemo 目录下的 Classes 和 Supporting Files 拷贝到项目的 ios/Mall 目录下 (与Images.xcassets文件夹同级)
 
拷贝文件
  • 将 Supporting Files 目录下的 Info.plist nim_debug.xcconfig nim_release.xcconfigmain.m 文件删除

  • NTESAppDelegate.m 内容和自己工程中的 AppDelegate.m 文件中的代码进行合并,并修改和去掉部分不需要的代码。

如下代码是我的AppDelegate.m文件的内容

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

#import "NTESLoginViewController.h"
#import "UIView+Toast.h"
#import "NTESService.h"
#import "NTESNotificationCenter.h"
#import "NTESLogManager.h"
#import "NTESDemoConfig.h"
#import "NTESSessionUtil.h"
#import "NTESMainTabController.h"
#import "NTESLoginManager.h"
#import "NTESCustomAttachmentDecoder.h"
#import "NTESClientUtil.h"
#import "NTESNotificationCenter.h"
#import "NIMKit.h"
#import "NTESSDKConfigDelegate.h"
#import "NTESCellLayoutConfig.h"
#import "NTESSubscribeManager.h"
#import "NTESRedPacketManager.h"
#import "NTESBundleSetting.h"



@import PushKit;

NSString *NTESNotificationLogout = @"NTESNotificationLogout";
@interface AppDelegate ()<NIMLoginManagerDelegate,PKPushRegistryDelegate>

@property (nonatomic,strong) NTESSDKConfigDelegate *sdkConfigDelegate;

@end


@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"Mall"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  
  [self initYunXin];
  
  return YES;
}

- (void)initYunXin
{
  [self setupNIMSDK];
  [self setupServices];
  [self registerPushService];
  [self commonInitListenEvents];
  
  // 因为本项目想实现的功能是启动进入的是 RN 界面,在需要的时候,从 RN 页面跳转到原生 iOS 界面
  //self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  //self.window.backgroundColor = [UIColor grayColor];
  //[self.window makeKeyAndVisible];
  //[application setStatusBarStyle:UIStatusBarStyleLightContent];
  
  //[self setupMainViewController];
}

- (void)dealloc
{
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  [[[NIMSDK sharedSDK] loginManager] removeDelegate:self];
}


#pragma mark - ApplicationDelegate
- (void)applicationWillResignActive:(UIApplication *)application {
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
  NSInteger count = [[[NIMSDK sharedSDK] conversationManager] allUnreadCount];
  [[UIApplication sharedApplication] setApplicationIconBadgeNumber:count];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
}

- (void)applicationWillTerminate:(UIApplication *)application {
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  [[NIMSDK sharedSDK] updateApnsToken:deviceToken];
  DDLogInfo(@"didRegisterForRemoteNotificationsWithDeviceToken:  %@", deviceToken);
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
  DDLogInfo(@"receive remote notification:  %@", userInfo);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
  DDLogError(@"fail to get apns token :%@",error);
}

#pragma mark PKPushRegistryDelegate
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
  if ([type isEqualToString:PKPushTypeVoIP])
  {
    [[NIMSDK sharedSDK] updatePushKitToken:credentials.token];
  }
}

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
  DDLogInfo(@"receive payload %@ type %@",payload.dictionaryPayload,type);
  NSNumber *badge = payload.dictionaryPayload[@"aps"][@"badge"];
  if ([badge isKindOfClass:[NSNumber class]])
  {
    [UIApplication sharedApplication].applicationIconBadgeNumber = [badge integerValue];
  }
}

- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(NSString *)type
{
  DDLogInfo(@"registry %@ invalidate %@",registry,type);
}


#pragma mark - openURL

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
  [[NTESRedPacketManager sharedManager] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
  return YES;
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
  [[NTESRedPacketManager sharedManager] application:app openURL:url options:options];
  return YES;
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
  //目前只有红包跳转
  return [[NTESRedPacketManager sharedManager] application:application handleOpenURL:url];
}


#pragma mark - misc
- (void)registerPushService
{
  //apns
  [[UIApplication sharedApplication] registerForRemoteNotifications];
  
  UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types
                                                                           categories:nil];
  [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
  
  //pushkit
  PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
  pushRegistry.delegate = self;
  pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
  
}

//- (void)setupMainViewController
//{
//  LoginData *data = [[NTESLoginManager sharedManager] currentLoginData];
//  NSString *account = [data account];
//  NSString *token = [data token];
//
//  //如果有缓存用户名密码推荐使用自动登录
//  if ([account length] && [token length])
//  {
//    NIMAutoLoginData *loginData = [[NIMAutoLoginData alloc] init];
//    loginData.account = account;
//    loginData.token = token;
//
//    [[[NIMSDK sharedSDK] loginManager] autoLogin:loginData];
//    [[NTESServiceManager sharedManager] start];
//    NTESMainTabController *mainTab = [[NTESMainTabController alloc] initWithNibName:nil bundle:nil];
//    self.window.rootViewController = mainTab;
//  }
//  else
//  {
//    [self setupLoginViewController];
//  }
//}

- (void)commonInitListenEvents
{
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(logout:)
                                               name:NTESNotificationLogout
                                             object:nil];
  
  [[[NIMSDK sharedSDK] loginManager] addDelegate:self];
}

//- (void)setupLoginViewController
//{
//  [self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
//  NTESLoginViewController *loginController = [[NTESLoginViewController alloc] init];
//  UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:loginController];
//  self.window.rootViewController = nav;
//}

#pragma mark - 注销
-(void)logout:(NSNotification *)note
{
  [self doLogout];
}

- (void)doLogout
{
  [[NTESLoginManager sharedManager] setCurrentLoginData:nil];
  [[NTESServiceManager sharedManager] destory];
//  [self setupLoginViewController];
}


#pragma NIMLoginManagerDelegate
-(void)onKick:(NIMKickReason)code clientType:(NIMLoginClientType)clientType
{
  NSString *reason = @"你被踢下线";
  switch (code) {
    case NIMKickReasonByClient:
    case NIMKickReasonByClientManually:{
      NSString *clientName = [NTESClientUtil clientName:clientType];
      reason = clientName.length ? [NSString stringWithFormat:@"你的帐号被%@端踢出下线,请注意帐号信息安全",clientName] : @"你的帐号被踢出下线,请注意帐号信息安全";
      break;
    }
    case NIMKickReasonByServer:
      reason = @"你被服务器踢下线";
      break;
    default:
      break;
  }
  [[[NIMSDK sharedSDK] loginManager] logout:^(NSError *error) {
    [[NSNotificationCenter defaultCenter] postNotificationName:NTESNotificationLogout object:nil];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"下线通知" message:reason delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
    [alert show];
  }];
}

- (void)onAutoLoginFailed:(NSError *)error
{
  

分类:

技术点:

相关文章: