# NIMSDKManager 使用指南 ## 目录 - [1. 概述](#1-概述) - [2. Objective-C 使用示例](#2-objective-c-使用示例) - [3. Swift 桥接使用示例](#3-swift-桥接使用示例) - [4. 配置说明](#4-配置说明) - [5. 最佳实践](#5-最佳实践) - [6. 常见问题](#6-常见问题) ## 1. 概述 `NIMSDKManager` 是一个专门用于管理NIMSDK事务的统一管理类,提供了配置、初始化、登录/登出等完整的功能封装。该类采用单例模式设计,支持Objective-C和Swift项目使用。 ### 1.1 主要功能 - **配置管理**: 统一的NIMSDK配置管理 - **初始化**: 简化的SDK初始化流程 - **登录管理**: 登录、自动登录、登出等功能 - **状态监控**: 实时监控登录状态变化 - **消息处理**: 消息发送、接收、广播等 - **推送管理**: APNS推送相关功能 - **代理管理**: 支持多代理监听 ### 1.2 设计特点 - **单例模式**: 全局统一管理 - **代理模式**: 支持多代理监听 - **Block回调**: 支持异步操作回调 - **Swift兼容**: 完美支持Swift项目桥接 - **错误处理**: 完善的错误处理机制 ## 2. Objective-C 使用示例 ### 2.1 基本配置和初始化 ```objc // 1. 创建配置模型 NIMSDKConfigModel *config = [[NIMSDKConfigModel alloc] init]; config.appKey = KeyWithType(KeyType_NetEase); config.apnsCername = @"pikoDevelopPush"; // DEBUG环境 config.shouldConsiderRevokedMessageUnreadCount = YES; config.shouldSyncStickTopSessionInfos = YES; config.enabledHttpsForInfo = NO; // DEBUG环境 config.enabledHttpsForMessage = NO; // DEBUG环境 // 2. 配置并初始化 [[NIMSDKManager sharedManager] configureWithConfig:config]; [[NIMSDKManager sharedManager] initializeWithCompletion:^(NSError * _Nullable error) { if (error) { NSLog(@"NIMSDK初始化失败: %@", error); } else { NSLog(@"NIMSDK初始化成功"); } }]; ``` ### 2.2 登录管理 ```objc // 1. 设置登录状态变化监听 [[NIMSDKManager sharedManager] setLoginStatusChangeBlock:^(NIMSDKLoginStatus status) { switch (status) { case NIMSDKLoginStatusNotLogin: NSLog(@"未登录"); break; case NIMSDKLoginStatusLogging: NSLog(@"登录中"); break; case NIMSDKLoginStatusLogined: NSLog(@"已登录"); break; case NIMSDKLoginStatusLogout: NSLog(@"已登出"); break; case NIMSDKLoginStatusKickout: NSLog(@"被踢出"); break; case NIMSDKLoginStatusAutoLoginFailed: NSLog(@"自动登录失败"); break; } }]; // 2. 执行登录 [[NIMSDKManager sharedManager] loginWithAccount:@"user123" token:@"token123" completion:^(NSError * _Nullable error) { if (error) { NSLog(@"登录失败: %@", error); } else { NSLog(@"登录成功"); } }]; // 3. 自动登录 NSDictionary *autoLoginData = @{@"account": @"user123", @"token": @"token123"}; [[NIMSDKManager sharedManager] autoLoginWithData:autoLoginData completion:^(NSError * _Nullable error) { if (error) { NSLog(@"自动登录失败: %@", error); } else { NSLog(@"自动登录成功"); } }]; // 4. 登出 [[NIMSDKManager sharedManager] logoutWithCompletion:^(NSError * _Nullable error) { if (error) { NSLog(@"登出失败: %@", error); } else { NSLog(@"登出成功"); } }]; ``` ### 2.3 代理监听 ```objc @interface MyViewController () @end @implementation MyViewController - (void)viewDidLoad { [super viewDidLoad]; // 添加代理 [[NIMSDKManager sharedManager] addDelegate:self]; } - (void)dealloc { // 移除代理 [[NIMSDKManager sharedManager] removeDelegate:self]; } #pragma mark - NIMSDKManagerDelegate - (void)nimSDKManager:(id)manager didChangeLoginStatus:(NIMSDKLoginStatus)status { NSLog(@"登录状态变化: %ld", (long)status); } - (void)nimSDKManager:(id)manager didAutoLoginFailed:(NSError *)error { NSLog(@"自动登录失败: %@", error); } - (void)nimSDKManager:(id)manager didKickout:(NIMLoginKickoutResult *)result { NSLog(@"被踢出: %@", result); } - (void)nimSDKManager:(id)manager didReceiveMessages:(NSArray *)messages { NSLog(@"收到消息: %@", messages); } - (void)nimSDKManager:(id)manager didReceiveBroadcastMessage:(NIMBroadcastMessage *)broadcastMessage { NSLog(@"收到广播消息: %@", broadcastMessage); } @end ``` ### 2.4 消息管理 ```objc // 1. 创建消息 NIMMessage *textMessage = [[NIMSDKManager sharedManager] createTextMessage:@"Hello World"]; // 2. 创建自定义消息 AttachmentModel *attachment = [[AttachmentModel alloc] init]; attachment.first = CustomMessageType_Gift; attachment.second = Custom_Message_Sub_Gift_Send; attachment.data = @{@"giftId": @"123", @"giftName": @"玫瑰花"}; NIMMessage *customMessage = [[NIMSDKManager sharedManager] createCustomMessageWithAttachment:attachment]; // 3. 发送消息 NIMSession *session = [NIMSession session:@"receiverId" type:NIMSessionTypeP2P]; [[NIMSDKManager sharedManager] sendMessage:textMessage toSession:session completion:^(NSError * _Nullable error) { if (error) { NSLog(@"发送失败: %@", error); } else { NSLog(@"发送成功"); } }]; // 4. 获取未读消息数 NSInteger unreadCount = [[NIMSDKManager sharedManager] unreadMessageCount]; NSLog(@"未读消息数: %ld", (long)unreadCount); // 5. 获取所有会话 NSArray *sessions = [[NIMSDKManager sharedManager] allRecentSessions]; NSLog(@"会话数量: %lu", (unsigned long)sessions.count); ``` ### 2.5 推送管理 ```objc // 1. 更新APNS设备Token - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [[NIMSDKManager sharedManager] updateApnsToken:deviceToken]; } // 2. 处理推送消息 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { BOOL handled = [[NIMSDKManager sharedManager] handlePushNotification:userInfo]; if (handled) { completionHandler(UIBackgroundFetchResultNewData); } else { completionHandler(UIBackgroundFetchResultNoData); } } ``` ## 3. Swift 桥接使用示例 ### 3.1 创建桥接头文件 在Swift项目中创建桥接头文件 `YourProject-Bridging-Header.h`: ```objc // // YourProject-Bridging-Header.h // YourProject // #ifndef YourProject_Bridging_Header_h #define YourProject_Bridging_Header_h #import "NIMSDKManager.h" #import "AttachmentModel.h" #import "CustomAttachmentDecoder.h" #endif /* YourProject_Bridging_Header_h */ ``` ### 3.2 Swift 使用示例 ```swift import Foundation import UIKit class NIMSDKService { static let shared = NIMSDKService() private let nimManager = NIMSDKManager.shared() private init() { setupNIMSDK() } // MARK: - 配置和初始化 private func setupNIMSDK() { // 创建配置 let config = NIMSDKConfigModel() config.appKey = KeyWithType(KeyType_NetEase) config.apnsCername = "pikoDevelopPush" // DEBUG环境 config.shouldConsiderRevokedMessageUnreadCount = true config.shouldSyncStickTopSessionInfos = true config.enabledHttpsForInfo = false // DEBUG环境 config.enabledHttpsForMessage = false // DEBUG环境 // 配置并初始化 nimManager.configure(with: config) nimManager.initialize { [weak self] error in if let error = error { print("NIMSDK初始化失败: \(error)") } else { print("NIMSDK初始化成功") self?.setupDelegates() } } } private func setupDelegates() { // 设置登录状态变化监听 nimManager.setLoginStatusChangeBlock { [weak self] status in self?.handleLoginStatusChange(status) } } // MARK: - 登录管理 func login(account: String, token: String, completion: @escaping (Error?) -> Void) { nimManager.login(withAccount: account, token: token) { error in DispatchQueue.main.async { completion(error) } } } func autoLogin(data: [String: Any], completion: @escaping (Error?) -> Void) { nimManager.autoLogin(with: data) { error in DispatchQueue.main.async { completion(error) } } } func logout(completion: @escaping (Error?) -> Void) { nimManager.logout { error in DispatchQueue.main.async { completion(error) } } } // MARK: - 状态查询 var isLogined: Bool { return nimManager.isLogined() } var currentAccount: String? { return nimManager.currentAccount() } var loginStatus: NIMSDKLoginStatus { return nimManager.currentLoginStatus() } // MARK: - 消息管理 func sendTextMessage(_ text: String, to sessionId: String, completion: @escaping (Error?) -> Void) { let message = nimManager.createTextMessage(text) let session = NIMSession(session: sessionId, type: .p2P) nimManager.send(message, to: session) { error in DispatchQueue.main.async { completion(error) } } } func sendCustomMessage(attachment: NIMCustomAttachment, to sessionId: String, completion: @escaping (Error?) -> Void) { let message = nimManager.createCustomMessage(with: attachment) let session = NIMSession(session: sessionId, type: .p2P) nimManager.send(message, to: session) { error in DispatchQueue.main.async { completion(error) } } } var unreadMessageCount: Int { return Int(nimManager.unreadMessageCount()) } var allRecentSessions: [NIMRecentSession] { return nimManager.allRecentSessions() ?? [] } // MARK: - 推送管理 func updateApnsToken(_ deviceToken: Data) { nimManager.updateApnsToken(deviceToken) } func handlePushNotification(_ userInfo: [AnyHashable: Any]) -> Bool { return nimManager.handlePushNotification(userInfo) } // MARK: - 私有方法 private func handleLoginStatusChange(_ status: NIMSDKLoginStatus) { switch status { case .notLogin: print("未登录") case .logging: print("登录中") case .logined: print("已登录") case .logout: print("已登出") case .kickout: print("被踢出") case .autoLoginFailed: print("自动登录失败") @unknown default: print("未知状态") } } } // MARK: - Swift 扩展 extension NIMSDKService { // 创建礼物消息的便捷方法 func createGiftMessage(giftId: String, giftName: String, giftCount: Int) -> NIMMessage? { let attachment = AttachmentModel() attachment.first = Int32(CustomMessageType_Gift) attachment.second = Int32(Custom_Message_Sub_Gift_Send) attachment.data = [ "giftId": giftId, "giftName": giftName, "giftCount": giftCount ] return nimManager.createCustomMessage(with: attachment) } // 发送礼物消息的便捷方法 func sendGift(giftId: String, giftName: String, giftCount: Int, to sessionId: String, completion: @escaping (Error?) -> Void) { guard let message = createGiftMessage(giftId: giftId, giftName: giftName, giftCount: giftCount) else { completion(NSError(domain: "NIMSDKService", code: -1, userInfo: [NSLocalizedDescriptionKey: "创建礼物消息失败"])) return } let session = NIMSession(session: sessionId, type: .p2P) nimManager.send(message, to: session) { error in DispatchQueue.main.async { completion(error) } } } } ``` ### 3.3 Swift 视图控制器使用示例 ```swift import UIKit class ChatViewController: UIViewController { private let nimService = NIMSDKService.shared override func viewDidLoad() { super.viewDidLoad() setupNIMSDK() } private func setupNIMSDK() { // 检查登录状态 if !nimService.isLogined { // 执行登录 nimService.login(account: "user123", token: "token123") { [weak self] error in if let error = error { print("登录失败: \(error)") } else { print("登录成功") self?.startChat() } } } else { startChat() } } private func startChat() { // 开始聊天功能 print("开始聊天") } // MARK: - 发送消息示例 @IBAction func sendTextMessage(_ sender: UIButton) { nimService.sendTextMessage("Hello from Swift!", to: "receiver123") { error in if let error = error { print("发送失败: \(error)") } else { print("发送成功") } } } @IBAction func sendGiftMessage(_ sender: UIButton) { nimService.sendGift(giftId: "123", giftName: "玫瑰花", giftCount: 1, to: "receiver123") { error in if let error = error { print("发送礼物失败: \(error)") } else { print("发送礼物成功") } } } // MARK: - 获取消息信息 func updateUnreadCount() { let count = nimService.unreadMessageCount print("未读消息数: \(count)") } func loadRecentSessions() { let sessions = nimService.allRecentSessions print("会话数量: \(sessions.count)") } } ``` ### 3.4 Swift AppDelegate 集成 ```swift import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? private let nimService = NIMSDKService.shared func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // NIMSDK已经在NIMSDKService中初始化 // 这里可以添加其他初始化代码 return true } // MARK: - 推送处理 func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { nimService.updateApnsToken(deviceToken) } func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { let handled = nimService.handlePushNotification(userInfo) completionHandler(handled ? .newData : .noData) } } ``` ## 4. 配置说明 ### 4.1 环境配置 ```objc // DEBUG环境配置 #ifdef DEBUG config.apnsCername = @"pikoDevelopPush"; config.enabledHttpsForInfo = NO; config.enabledHttpsForMessage = NO; #else config.apnsCername = @"newPiko"; config.enabledHttpsForInfo = YES; config.enabledHttpsForMessage = YES; #endif ``` ### 4.2 AppKey配置 ```objc // 从常量文件获取AppKey config.appKey = KeyWithType(KeyType_NetEase); // 或者直接设置 config.appKey = @"your_app_key_here"; ``` ### 4.3 推送配置 确保在项目中正确配置了APNS证书,并在配置中设置正确的证书名称。 ## 5. 最佳实践 ### 5.1 初始化时机 - 在App启动时尽早初始化NIMSDK - 确保在用户登录前完成初始化 ### 5.2 错误处理 - 对所有异步操作添加错误处理 - 在UI线程中处理回调结果 ### 5.3 内存管理 - 及时移除不需要的代理 - 避免循环引用 ### 5.4 状态管理 - 监听登录状态变化 - 根据状态变化更新UI ### 5.5 Swift集成 - 使用桥接头文件正确导入Objective-C类 - 在Swift中创建便捷的包装方法 ## 6. 常见问题 ### 6.1 编译错误 **Q: 编译时提示找不到NIMSDK头文件** A: 确保正确导入了NIMSDK框架,并在桥接头文件中正确导入。 ### 6.2 初始化失败 **Q: NIMSDK初始化失败** A: 检查AppKey是否正确,网络连接是否正常。 ### 6.3 登录问题 **Q: 登录后立即被踢出** A: 检查账号是否在其他设备登录,或者Token是否过期。 ### 6.4 Swift桥接问题 **Q: Swift中无法使用NIMSDKManager** A: 确保在桥接头文件中正确导入了相关头文件。 ### 6.5 推送问题 **Q: 推送通知无法接收** A: 检查APNS证书配置,确保设备Token正确上传。 --- **文档版本**: 1.0 **最后更新**: 2024年12月 **维护人员**: 开发团队