锁屏时的效果 | 在后台时的效果 |
![]() | ![]() |
target 'YourAppName' do# Uncommment the next line if you're using Swift or would like to use dynamic frameworksuse_frameworks!use_modular_headers!# Pods for Examplepod 'TIMPush', '7.9.5668'end
pod install # 如果无法安装 TUIKit 最新版本,执行以下命令更新本地的 CocoaPods 仓库列表。 pod repo update


Push Notification 的 Service。Bundle ID 不能使用通配符 *,否则将无法使用远程推送服务。Bundle ID等其他信息,单击 Continue 进行下一步。

SSL Certificate ,分别用于开发环境(Development)和生产环境(Production)的远程推送证书。Development)的 Create Certificate,系统将提示我们需要一个Certificate Signing Request(CSR)。Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority)。
*.certSigningRequest 文件。第3步 中 Apple Developer 网站刚才的页面,单击 “Choose File” 上传生成的*.certSigningRequest文件。
Development SSL Certificate 到本地。Production SSL Certificate 下载到本地。Sandbox)+生产(Production)的合并证书,可以同时作为开发环境和生产环境的证书使用。SSL Certificate,系统会将其导入钥匙串中。Apple Development iOS Push Service)和生产环境(Apple Push Services)的 P12 文件。P12文件时,请务必要为其设置密码。



- businessID 协议方法返回证书 ID 即可。#pragma mark - TIMPush//Swift 务必携带 @objc 关键字@objc func businessID() -> Int32 {//上一步控制台给的证书IDreturn 0}@objc func applicationGroupID() -> String {//AppGroup IDreturn "group.com.yourcompony.pushkey"}@objc func onRemoteNotificationReceived(_ notice: String?) -> Bool {// custom navigatereturn false}
#pragma mark - TIMPush- (int)businessID {//上一步控制台给的证书ID,如 1234567int kBusinessID = 1234567;return kBusinessID;}- (NSString *)applicationGroupID {//AppGroup IDreturn kTIMPushAppGroupKey;}- (BOOL)onRemoteNotificationReceived:(NSString *)notice {// custom navigatereturn NO;}
import TUICallKit_Swiftimport RTCRoomEnginelet pushInfo: TUIOfflinePushInfo = TUIOfflinePushInfo()pushInfo.title = ""pushInfo.desc = "您有一个新的通话"pushInfo.iOSPushType = .apnspushInfo.ignoreIOSBadge = falsepushInfo.iOSSound = "phone_ringing.mp3"pushInfo.androidSound = "phone_ringing"// OPPO必须设置ChannelID才可以收到推送消息,这个channelID需要和控制台一致// OPPO must set a ChannelID to receive push messages. This channelID needs to be the same as the console.pushInfo.androidOPPOChannelID = "tuikit"// FCM channel ID, you need change PrivateConstants.java and set "fcmPushChannelId"pushInfo.androidFCMChannelID = "fcm_push_channel"// VIVO message type: 0-push message, 1-System message(have a higher delivery rate)pushInfo.androidVIVOClassification = 1// HuaWei message type: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835pushInfo.androidHuaWeiCategory = "IM"let params = TUICallParams()params.userData = "User Data"params.timeout = 30params.offlinePushInfo = pushInfoTUICallKit.createInstance().calls(userIdList: ["123456"], callMediaType: .audio, params: params) {} fail: { code, message in}
#import <TUICallKit_Swift/TUICallKit_Swift-Swift.h>#import <RTCRoomEngine/TUICallEngine.h>- (TUICallParams *)getCallParams {TUIOfflinePushInfo *offlinePushInfo = [self createOfflinePushInfo];TUICallParams *callParams = [TUICallParams new];callParams.offlinePushInfo = offlinePushInfo;callParams.timeout = 30;return callParams;}- (TUIOfflinePushInfo *)createOfflinePushInfo {TUIOfflinePushInfo *pushInfo = [TUIOfflinePushInfo new];pushInfo.title = @"";pushInfo.desc = @"您有一个新的通话";pushInfo.iOSPushType = TUICallIOSOfflinePushTypeAPNs;pushInfo.ignoreIOSBadge = NO;pushInfo.iOSSound = @"phone_ringing.mp3";pushInfo.AndroidSound = @"phone_ringing";// OPPO必须设置ChannelID才可以收到推送消息,这个channelID需要和控制台一致// OPPO must set a ChannelID to receive push messages. This channelID needs to be the same as the console.pushInfo.AndroidOPPOChannelID = @"tuikit";// FCM channel ID, you need change PrivateConstants.java and set "fcmPushChannelId"pushInfo.AndroidFCMChannelID = @"fcm_push_channel";// VIVO message type: 0-push message, 1-System message(have a higher delivery rate)pushInfo.AndroidVIVOClassification = 1;// HuaWei message type: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835pushInfo.AndroidHuaWeiCategory = @"IM";return pushInfo;}[[TUICallKit createInstance] calls:@[@"123456"]callMediaType:TUICallMediaTypeAudioparams:[self getCallParams] succ:^{} fail:^(int code, NSString * _Nullable errMsg) {}];
[[TUICallKit createInstance] call:@"mike 的 id" params:[self getCallParams] callMediaType:TUICallMediaTypeVideo];- (TUICallParams *)getCallParams {TUIOfflinePushInfo *offlinePushInfo = [self createOfflinePushInfo];TUICallParams *callParams = [TUICallParams new];callParams.offlinePushInfo = offlinePushInfo;callParams.timeout = 30;return callParams;}+ (TUIOfflinePushInfo *)createOfflinePushInfo {TUIOfflinePushInfo *pushInfo = [TUIOfflinePushInfo new];pushInfo.title = @"";pushInfo.desc = TUICallingLocalize(@"TUICallKit.have.new.invitation");pushInfo.iOSPushType = TUICallIOSOfflinePushTypeAPNs;pushInfo.ignoreIOSBadge = NO;pushInfo.iOSSound = @"phone_ringing.mp3";pushInfo.AndroidSound = @"phone_ringing";// OPPO必须设置ChannelID才可以收到推送消息,这个channelID需要和控制台一致// OPPO must set a ChannelID to receive push messages. This channelID needs to be the same as the console.pushInfo.AndroidOPPOChannelID = @"tuikit";// FCM channel ID, you need change PrivateConstants.java and set "fcmPushChannelId"pushInfo.AndroidFCMChannelID = @"fcm_push_channel";// VIVO message type: 0-push message, 1-System message(have a higher delivery rate)pushInfo.AndroidVIVOClassification = 1;// HuaWei message type: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835pushInfo.AndroidHuaWeiCategory = @"IM";return pushInfo;}
let params = TUICallParams()let pushInfo: TUIOfflinePushInfo = TUIOfflinePushInfo()pushInfo.title = "TUICallKit"pushInfo.desc = "TUICallKit.have.new.invitation"pushInfo.iOSPushType = .apnspushInfo.ignoreIOSBadge = falsepushInfo.iOSSound = "phone_ringing.mp3"pushInfo.androidSound = "phone_ringing"// OPPO必须设置ChannelID才可以收到推送消息,这个channelID需要和控制台一致// OPPO must set a ChannelID to receive push messages. This channelID needs to be the same as the console.pushInfo.androidOPPOChannelID = "tuikit"// FCM channel ID, you need change PrivateConstants.java and set "fcmPushChannelId"pushInfo.androidFCMChannelID = "fcm_push_channel"// VIVO message type: 0-push message, 1-System message(have a higher delivery rate)pushInfo.androidVIVOClassification = 1// HuaWei message type: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/message-classification-0000001149358835pushInfo.androidHuaWeiCategory = "IM"params.userData = "User Data"params.timeout = 30params.offlinePushInfo = pushInfoTUICallKit.createInstance().call(userId: "123456", callMediaType: .audio, params: params) {} fail: {code, message in}
Notification Service Extension实现持续的震动,首先需要在控制台开启 mutable-content 开关。
Editor > Add Target > Notification Service Extension 来创建一个 Extension。新创建的 Extension Target 需要配置 Apple 证书,具体方法可以 参考这里。// NotificationService.swiftimport UserNotificationsclass NotificationService: UNNotificationServiceExtension {var contentHandler: ((UNNotificationContent) -> Void)?var bestAttemptContent: UNMutableNotificationContent?override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {self.contentHandler = contentHandlerbestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)if let bestAttemptContent = bestAttemptContent {// Modify the notification content here...bestAttemptContent.title = "\\(bestAttemptContent.title) [modified]"contentHandler(bestAttemptContent)}}override func serviceExtensionTimeWillExpire() {// Called just before the extension will be terminated by the system.// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {contentHandler(bestAttemptContent)}}}
// NotificationService.swiftimport UserNotificationsclass NotificationService: UNNotificationServiceExtension {var contentHandler: ((UNNotificationContent) -> Void)?var bestAttemptContent: UNMutableNotificationContent?override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {self.contentHandler = contentHandlerbestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)if let bestAttemptContent = bestAttemptContent {contentHandler(bestAttemptContent)}// start ringing, VibratorFeature.start() needs to be implemented by yourselfVibratorFeature.start()}override func serviceExtensionTimeWillExpire() {if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {/// If there is no response for more than 30 seconds, the vibration and ringing function will be turned off.// stop ringing, RingingFeature.shared.stop() needs to be implemented by yourselfVibratorFeature.stop()contentHandler(bestAttemptContent)}}}
VibratorFeature.start()、VibratorFeature.stop()需要客户自行实现。// iOS 13 之前的版本通过 AppDelegate applicationWillEnterForeground 监测前后台状态// AppDelegate.swiftclass AppDelegate: UIResponder, UIApplicationDelegate {func applicationWillEnterForeground(_ application: UIApplication) {……sendStopRingingToExtension()}func sendStopRingingToExtension() {CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(),CFNotificationName("APNsStopRinging" as CFString), nil, nil, true)}}// iOS 13 及以后版本通过 SceneDelegate sceneWillEnterForeground 监测前后台状态// SceneDelegate.swiftclass SceneDelegate: UIResponder, UIWindowSceneDelegate {func sceneWillEnterForeground(_ scene: UIScene) {……sendStopRingingToExtension()}func sendStopRingingToExtension() {CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(),CFNotificationName("APNsStopRinging" as CFString), nil, nil, true)}}
// NotificationService.swiftimport UserNotificationsclass NotificationService: UNNotificationServiceExtension {var contentHandler: ((UNNotificationContent) -> Void)?var bestAttemptContent: UNMutableNotificationContent?override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {self.contentHandler = contentHandlerbestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)if let bestAttemptContent = bestAttemptContent {contentHandler(bestAttemptContent)}// start ringing, VibratorFeature.start() needs to be implemented by yourselfVibratorFeature.start()registerObserver()}override func serviceExtensionTimeWillExpire() {if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {/// If there is no response for more than 30 seconds, the vibration and ringing function will be turned off.// stop ringing, RingingFeature.shared.stop() needs to be implemented by yourselfVibratorFeature.stop()contentHandler(bestAttemptContent)}}private func registerObserver() {CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),Unmanaged.passUnretained(self).toOpaque(), { center, pointer, name, _, userInfo inVibratorFeature.stop()}, "APNsStopRinging" as CFString, nil, .deliverImmediately)}}
文档反馈