实现微信长震动只能在Xcode10版本中实现. 在新版本Xcode11上至于后台或杀死报错,
报错reason: 'PushKit apps that use VoIP push must link either CallKit or IncomingCallNotifications frameworks.'
需要实现callkit , 苹果官方提供的语音通话库. 但是在大陆审核好像不通过.
如果需要Xcode 11降为 Xcode 10, 可以看我的另一篇文章.
//导入pushkit库
#import
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
//注册VOIP
PKPushRegistry *voipRegistry = [[PKPushRegistry alloc] initWithQueue:nil];
voipRegistry.delegate=self;
voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
//实现 PKPushRegistryDelegate 协议
//绑定 VoIP Token
- (void)pushRegistry:(PKPushRegistry*)registry didUpdatePushCredentials:(PKPushCredentials*)credentials forType:(NSString*)type {
//向服务器注册 VoipToken 为了方便开发者,建议使用新方法
NSString *voipToken = [[[[credentials.token description] stringByReplacingOccurrencesOfString: @"<" withString: @""]
stringByReplacingOccurrencesOfString: @">" withString: @""] stringByReplacingOccurrencesOfString: @" " withString: @""];
}
//接收 VoIP 推送处理具体业务逻辑
- (void)pushRegistry:(PKPushRegistry*)registry didReceiveIncomingPushWithPayload:(PKPushPayload*)payload forType:(NSString*)type {
// TODO:接收 VoIP 推送中的 Payload 信息进行业务处理。
NSLog(@"[VoIP Payload]:%@,%@", payload, payload.dictionaryPayload);
NSDictionary*apnsDic = payload.dictionaryPayload[@"aps"];
// 长震动+铃声 (手机静音状态下不能实现,建议使用下面方法)
// SystemSoundID sound;
// NSString *path = [[NSBundle mainBundle] pathForResource:@"pushSoundCall" ofType:@"caf"];
// AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &sound);
// AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate, NULL, NULL, &vibrationCallback, NULL);
// AudioServicesAddSystemSoundCompletion(sound, NULL, NULL, &soundCallback, NULL);
// AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
// AudioServicesPlaySystemSound(sound);
//长震动 + 铃声(以本地推送添加铃声文件方法实现, 铃声长度30s内), (手机静音状态下无音,但是震动存在)
AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate, NULL, NULL, &vibrationCallback, NULL);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
//本地推送
[self VOIPCustomUNNotification:apnsDic];
}
- (SystemSoundID)getSystemSoundID {
SystemSoundID sound;
NSString *path = [[NSBundle mainBundle] pathForResource:@"pushSoundCall" ofType:@"caf"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &sound);
returnsound;
}
///开始震动
- (void)startVibrator {
AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate, NULL, NULL, soundCallback, NULL);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
///结束震动
- (void)stopVibrator {
SystemSoundIDsound = [selfgetSystemSoundID];
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
AudioServicesRemoveSystemSoundCompletion(sound);
AudioServicesDisposeSystemSoundID(kSystemSoundID_Vibrate);
AudioServicesDisposeSystemSoundID(sound);
}
///循环结束震动
voidsoundCallback(SystemSoundIDsound,void* clientData) {
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
AudioServicesRemoveSystemSoundCompletion(sound);
AudioServicesDisposeSystemSoundID(kSystemSoundID_Vibrate);
AudioServicesDisposeSystemSoundID(sound);
}
//震动完成回调,因为震动一下便会调用一次,这里延迟800ms再继续震动,和微信差不多,时间长短可自己控制。参数sound即为注册回调时传的第一个参数
voidvibrationCallback(SystemSoundIDsound,void* clientData) {
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(800 * NSEC_PER_MSEC)), dispatch_get_global_queue(0, 0), ^{
// AudioServicesPlaySystemSound(sound);
// });
AudioServicesPlaySystemSound(sound);
}
- (void)VOIPCustomUNNotification:(NSDictionary*)apnsDic {
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionBadge|UNAuthorizationOptionSound|UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError * _Nullable error){
if(granted) {
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc]init];
content.title= apnsDic[@"alert"];
content.subtitle= [NSStringstringWithFormat:@"%@", apnsDic];
content.body=@"body";
//铃声放在这里.手机静音状态下无音(不可避免).铃声长度30s内
content.sound=[UNNotificationSound soundNamed:@"pushSoundCall.caf"];
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.01 repeats:NO];
UNNotificationRequest*request = [UNNotificationRequestrequestWithIdentifier:@"messageId"content:contenttrigger:trigger];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if(!error) {
}
}];
}
}];
}