我正在制作一个我希望实施Apple推送通知服务的应用程序。我按照this tutorial中给出的分步说明进行操作。
但是,这些方法仍未被调用。我不知道造成这个问题的原因。任何人都可以帮助我吗?
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
//NSString * token = [[NSString alloc] initWithData:deviceTokenencoding:NSUTF8StringEncoding];
NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
NSLog(@"Device Token:%@",str);
//NSLog(@"Device token is called");
//const void *devTokenBytes = [deviceToken bytes];
//NSLog(@"Device Token");
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSString *str = [NSString stringWithFormat: @"Error: %@", err];
NSLog(@"Error:%@",str);
}
答案 0 :(得分:69)
我遇到了同样的问题:调用registerForRemoteNotificationTypes:
既未调用application:didRegisterForRemoteNotificationsWithDeviceToken:
也未调用application:didFailToRegisterForRemoteNotificationsWithError:
我最终在Apple的技术说明TN2265的帮助下解决了这个问题。
这就是我所做的:
首先,我仔细检查了我确实是registering correctly for Push Notifications,包括验证我的“aps-environment”密钥的配置文件以及.app文件本身的代码签名。我把这一切都设置得正确。
然后我必须在控制台中调试推送通知状态消息(您需要在设备上安装PersistentConnectionLogging.mobileconfig配置文件并重新启动它。请参阅“观察推送状态消息”下的TN2265)。我注意到apns进程启动了一个计时器并计算了一个最小的开火日期,这让我怀疑APN正在通过推送通知注册确认消息,如TN2265所示:
重置iOS上的推送通知权限警报
第一次启用推送的应用注册推送通知时,iOS会询问用户是否希望接收该应用的通知。一旦用户响应此警报,除非设备已恢复或应用程序已卸载至少一天,否则不会再次显示该警报。
如果您想模拟首次运行的应用,可以将应用程序卸载一天。通过将系统时钟向前设置一天或更长时间,完全关闭设备,然后重新打开设备,您可以实现后者而无需实际等待一天。
因此,我从设备中删除了该应用,然后在“设置”中手动更改了iPhone的日期,重新启动了该设备,并重新安装了该应用。
下次我的代码调用registerForRemoteNotificationTypes
时,它会按预期收到回调。
这解决了我的问题。希望能帮助到你。
答案 1 :(得分:66)
在iOS 8中,不推荐使用某些方法。按照以下步骤进行iOS 8兼容性
if([[UIDevice currentDevice] systemVersion].floatValue >= 8.0)
{
UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge)];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
//For interactive notification only
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:@"declineAction"]){
}
else if ([identifier isEqualToString:@"answerAction"]){
}
}
注意:除了didRegisterForRemoteNotificationsWithDeviceToken
和didReceiveRemoteNotification
之外,iOS 8还需要以上两种新方法。否则将不会调用委托方法。
答案 2 :(得分:26)
在 iOS 8 中,除了以不同方式请求推送通知访问外,您还需要以不同方式注册。
请求访问:
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
// iOS 8
UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
// iOS 7 or iOS 6
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
处理注册设备:
// New in iOS 8
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[application registerForRemoteNotifications];
}
// iOS 7 or iOS 6
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
// Send token to server
}
答案 3 :(得分:12)
确保拨打电话(根据支持的通知类型进行更新)
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
,配置文件已启用APNS。启用APNS后,您可能需要重新下载配置文件。如果您遇到麻烦并且出现错误,那么也许您应该创建一个Entitlements.plist并添加具有值“development”或“production”的密钥“aps-environment”,具体取决于构建的类型(通常这个键值对是包含在配置文件中,但有时Xcode会混淆它们。)
答案 4 :(得分:11)
请记住,模拟器中不支持远程通知。因此,如果您在模拟器中运行应用程序,则不会调用didRegisterForRemoteNotificationsWithDeviceToken
。
答案 5 :(得分:6)
如果在启用和配置Apple推送通知服务之前使用配置文件,则需要再次重新下载配置文件。
从Xcode Organizer和iPhone / iPad删除配置文件。
转到Settings -> General -> Profiles -> [Your provisioning] -> Remove
。
安装新下载的配置文件。然后从XCode清理并运行项目。
现在应该调用didRegisterForRemoteNotificationsWithDeviceToken
。
答案 6 :(得分:3)
我犯了一个错误,忽略了一个引导我的实施细节。我试图想象一下,并在应用程序入门过程中向用户询问推送通知,因此我将registerForRemoteNotificationTypes
,didRegisterForRemoteNotificationsWithDeviceToken
和didFailToRegisterForRemoteNotificationsWithError
全部放在自定义UIView中。
FIX:didRegisterForRemoteNotificationsWithDeviceToken
和didFailToRegisterForRemoteNotificationsWithError
需要在UIApplicationDelegate
(YourAppDelegate.m
)中触发。
答案 7 :(得分:3)
确保您的互联网连接已开启。 由于互联网连接,我花了几个小时才收到工作通知。
答案 8 :(得分:3)
如果您已将推送添加到现有应用ID,请确保重新生成配置文件。如果您不这样做,该配置文件将不会知道您是否启用了推送应用程序ID。
答案 9 :(得分:3)
试试这个为我工作,
第一步
UIApplication *application = [UIApplication sharedApplication];
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge
|UIUserNotificationTypeSound
|UIUserNotificationTypeAlert) categories:nil];
[application registerUserNotificationSettings:settings];
}
else {
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
在上面的方法中添加以下代码
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:@"declineAction"]){
}
else if ([identifier isEqualToString:@"answerAction"]){
}
}
#endif
第二步
添加以下代码功能
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
您将在以下功能中获得设备令牌
$sql = "SELECT * FROM climbs
WHERE userlogged = (SELECT user_id FROM users WHERE username = $user)
";
详情请参阅This
希望这对某些人有帮助。
答案 10 :(得分:2)
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions{ //Overridepointforcustomizationafterapplicationlaunch.
//Addtheviewcontroller’sviewtothewindowanddisplay. [windowaddSubview:viewController.view]; [windowmakeKeyAndVisible];
NSLog(@”Registering for push notifications...”);
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)];
returnYES;
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
}
NSString *str = [NSString stringWithFormat:@”Device Token=%@”,deviceToken];
NSLog(@”%@”, str);
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSString *str = [NSString stringWithFormat: @”Error: %@”, err]; NSLog(@”%@”, str);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
for (id key in userInfo) { NSLog(@”key: %@, value: %@”, key, [userInfo objectForKey:key]);
}
答案 11 :(得分:2)
获取设备令牌的最低要求:无需配置应用ID,配置或证书等,因此无需设置代码签名调用委托方法 didRegisterForRemoteNotificationsWithDeviceToken 。
我刚刚在Xcode 7中创建了一个新的iOS项目,用于默认设置的单视图,并提供了一个随机的bundle id,如com.mycompany.pushtest,它没有在apple dev portal中配置。
使用以下代码,我可以在iPad上的didRegisterForRemoteNotificationsWithDeviceToken方法中使用 Internet 访问WIFI获取我的设备令牌。我的设备已连接,我只是直接从xcode运行应用程序并在xcode的控制台中查看值。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
}
else
{
// Register for Push Notifications, if running iOS version < 8
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
}
return YES;
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"Error: %@", error.description);
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceToken);
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
NSLog(@"NotificationSettings: %@", notificationSettings);
}
答案 12 :(得分:1)
我对此有一点意见。最近我也面临这个问题。我已经做了一切 根据文件,但委托方法没有调用。最后我看到了 一篇文章说网络问题。然后我改变了网络和 它工作正常。所以关心网络也因为很少有网络可以阻止 APNS。
答案 13 :(得分:1)
如果关闭app的推送消息,
永远不会调用appdidRegisterForRemoteNotificationsWithDeviceToken答案 14 :(得分:1)
浪费了最烦人的3小时后,请按照以下步骤解决此问题:
删除应用
重置设备
再次运行
它奏效了
答案 15 :(得分:0)
这件事发生在我身上,因为我重置了&amp;删除了手机上的所有数据(想要开发电话使用)。再次设置手机后,这会阻止APN连接。
我尝试过各种各样的东西,但唯一能解决的问题就是将手机设置为与新SIM卡下的运营商合作。
此链接提供了有关可能发生的事情的更多提示:https://developer.apple.com/library/ios/technotes/tn2265/_index.html
它表示APN试图通过运营商/塔优先连接而不是wifi。也许这个问题也发生在wifi网络上阻塞端口5223的路由器上,但我对此表示怀疑,因为它在全局重置发生之前的前一天工作正常。
答案 16 :(得分:0)
对我来说,解决了它的目的是构建设置和代码签名部分,手动选择代码签名标识和配置文件。显然,自动设置没有找到正确的设置,因此应用程序没有得到适当的授权。
答案 17 :(得分:0)
另外,请勿忘记检查Apple https://developer.apple.com/system-status/的系统状态。
我尝试过上面发布的所有解决方案,但最终的错误是因为APNS服务已关闭!第二天所有人都按预期再次工作。
此外,您的回调方法中有一个拼写错误:
- (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
由于Rupesh指出正确的方法名称是:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
这可能就是你在案件中从未收到过令牌的原因!
答案 18 :(得分:0)
您需要从didFinishLaunchingWithOptions调用registerForNotifications方法。
func registerForNotifications(){
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options:[.alert,.sound,.badge]) { (granted, error) in
if granted{
UIApplication.shared.registerForRemoteNotifications()
}else{
print("Notification permission denied.")
}
}
} else {
// For iOS 9 and Below
let type: UIUserNotificationType = [.alert,.sound,.badge];
let setting = UIUserNotificationSettings(types: type, categories: nil);
UIApplication.shared.registerUserNotificationSettings(setting);
UIApplication.shared.registerForRemoteNotifications()
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = String(format: "%@", deviceToken as CVarArg).trimmingCharacters(in: CharacterSet(charactersIn: "<>")).replacingOccurrences(of: " ", with: "")
print(token)
}
extension AppDelegate : UNUserNotificationCenterDelegate{
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) {
print("Handle push from foreground”)
let info = ((notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary)
if let type = info.value(forKey: "type") as? Int{
if type == 0 {
// notification received ,Handle your notification here
}
}
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("Handle push from background or closed")
let info = ((response.notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary)
if let type = info.value(forKey: "type") as? Int{
if type == 0 {
// notification received ,Handle your notification here
}
}
}
}
答案 19 :(得分:0)
我有一个不同的问题,其中我的推送通知回调被第三方库劫持,我已经包含,即Firebase。这些库调用push通知回调方法来获取回调。
希望这有助于某人。