Thông báo từ xa iOS 8


Câu trả lời:


180

Đọc mã trong UIApplication.h.

Bạn sẽ biết làm thế nào để làm điều đó.

Đầu tiên:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

thêm mã như thế này

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
#ifdef __IPHONE_8_0
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert 
      | UIUserNotificationTypeBadge 
      | UIUserNotificationTypeSound) categories:nil];
  [application registerUserNotificationSettings:settings];
#endif
} else {
  UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
  [application registerForRemoteNotificationTypes:myTypes];
}

nếu bạn không sử dụng cả Xcode 5 và Xcode 6 , hãy thử mã này

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
      |UIRemoteNotificationTypeSound
      |UIRemoteNotificationTypeAlert) categories:nil];
  [application registerUserNotificationSettings:settings];
} else {
  UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
  [application registerForRemoteNotificationTypes:myTypes];
}

(Cảm ơn lời nhắc của @zeiteisen @dmur)


Thứ hai:

Thêm chức năng này

#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

Và bạn có thể đưa deviceToken vào

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

nếu nó vẫn không hoạt động, hãy sử dụng chức năng này và NSLog lỗi

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error

4
Điều này. Thật khó hiểu, Apple đã không cập nhật tài liệu của họ UIUserNotificationSettingshoặc UIApplicationnói về cách điều này được yêu cầu cho iOS 8. Thay vào đó, nó bị chôn vùi trong các điểm khác biệt về API của họ.
Hyperbole

27
Điều này sẽ xảy ra trên các phiên bản iOS bên dưới iOS 8. #ifdef là một hàm COMPILER và được đánh giá tại thời điểm biên dịch. Bạn vẫn cần kiểm tra thời gian chạy!
Dan VanWinkle

4
Sử dụng macro này để kiểm tra iOS 8: #define isAtLeastiOS8 ([[[UIDevice currentDevice] systemVersion] floatValue]> = 8.0). __IPHONE_8_0 không phải là một kiểm tra tốt vì bạn cũng muốn mã này tiếp tục chạy trên các phiên bản trong tương lai.
er0

2
Điều đó nói rằng, trong trường hợp này, #ifdef là không cần thiết, trừ khi nhóm của bạn đang sử dụng cả Xcode 5 và Xcode 6. Thay vào đó, bạn nên if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {kiểm tra, như zeiteisen đã làm trong câu trả lời của anh ấy.
dmur

6
Sửa một chút cho enum UIRemoteNotificationType không dùng nữa: NS_ENUM_DEPRECATED_IOS (3_0, 8_0, "Sử dụng UIUserNotificationType cho thông báo của người dùng và registerForRemoteNotifications để nhận thông báo từ xa."); Vì vậy, đối với iOS 8 trở lên, bạn phải sử dụng UIUserNotificationTypeBadge, UIUserNotificationTypeSound, UIUserNotificationTypeAlert. (UIUserNotificationType cho các phiên bản mới, UIRemoteNotificationType - cho các phiên bản cũ hơn). Các tổng hợp được xác định trong <UIKit / UIApplication.h> và <UIKit / UIUserNotificationSettings.h>
KepPM

75

Cách đăng ký iOS 8 và tiếp tục hỗ trợ các phiên bản cũ hơn

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];
}

và trong ứng dụng ủy quyền thêm

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}

iOS8 có thể nhận thông báo im lặng mà không cần xin phép. Gọi điện thoại - (void)registerForRemoteNotifications. Sau đó application:didRegisterForRemoteNotificationsWithDeviceToken:sẽ được gọi là

Lưu ý: lệnh gọi lại với mã thông báo chỉ được gọi nếu ứng dụng đã đăng ký thành công thông báo người dùng bằng chức năng bên dưới hoặc nếu tính năng Làm mới ứng dụng nền được bật.

Kiểm tra ứng dụng Cài đặt cho bạn nếu bất kỳ loại thông báo nào được bật. Nếu không, bạn sẽ không nhận được mã thông báo thiết bị.

Giờ đây, bạn có thể nhận thông báo im lặng với

aps {
content-available: 1
}

trong tải thông báo

Nhưng thông báo xuất hiện vẫn cần sự cho phép. Gọi

UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[application registerUserNotificationSettings:notificationSettings];

Mã này nên yêu cầu sự cho phép.

Bây giờ bạn đã sẵn sàng để nhận thông báo đẩy


1
cảm ơn bạn cho một OS8 can receive silent notifications without asking for permissionchút. Điều đó đã khiến tôi phát điên và đây là nơi duy nhất tôi tìm thấy một chút hữu ích!
sbauch

@zeiteisen, trong iftuyên bố đầu tiên của bạn , bạn nên sử dụng UIUserNotificationTypeSoundthay vì UIRemoteNotificationTypeSound, vì UIRemoteNotificationTypekhông được dùng trong iOS 8.
Tanner Semerad

Ai đó có thể giải thích tại sao lệnh gọi lại với mã thông báo chỉ được gọi khi tính năng Làm mới ứng dụng nền được bật không? Tôi mặc dù nó nên được gọi khi sự cho phép Push Notification được kích hoạt ...
guilherme.minglini

15

Trong trường hợp của tôi, tôi đã thực hiện các bản cập nhật cần thiết để yêu cầu quyền truy cập thông báo đẩy cho iOS 7 và iOS 8, tuy nhiên, tôi đã không triển khai lệnh gọi lại mới khi người dùng iOS 8 cấp quyền truy cập. Tôi cần thêm phương thức này vào đại biểu ứng dụng của mình.

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}

1

Nếu bạn đang sử dụng Xamarin.iOS để xây dựng ứng dụng di động của mình, bạn có thể sử dụng đoạn mã này để yêu cầu đăng ký thông báo đẩy

if (UIDevice.CurrentDevice.CheckSystemVersion(8,0))
{
    UIUserNotificationType userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
    UIUserNotificationSettings settings = UIUserNotificationSettings.GetSettingsForTypes(userNotificationTypes, null);
    UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
else
{
    UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
    UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
} 

Ngoài ra, bạn sẽ cần ghi đè DidRegisterUserNotificationSettingsphương thức để lấy mã thông báo thiết bị được trả về từ máy chủ APNS:

public override void DidRegisterUserNotificationSettings(UIApplication application, UIUserNotificationSettings notificationSettings)
{
    application.RegisterForRemoteNotifications();
}

1

Câu trả lời của Madao ( https://stackoverflow.com/a/24488562/859742 ) là đúng nhưng ....

UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge

nên "đúng" hơn

UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];

Các cờ đó có cùng giá trị mặt nạ bit và đó là lý do tại sao cả hai sẽ hoạt động nhưng không UIUserNotificationSettingsyêu cầu .UIUserNotificationTypeUIRemoteNotificationType

Ngoài ra tôi sẽ gọi

[application registerUserNotificationSettings:settings];

Trong AppDelegatephương thức (tùy thuộc vào quyền được cấp),

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings

Có gì khác biệt?
Vladimir Stazhilov

1
UIUserNotificationTypeBadge và UIRemoteNotificationTypeBadge là mặt nạ chút tương tự, nhưng điều có ý nghĩa khác nhau =)
Ilker Baltaci

0

Tôi nghĩ rằng cách tốt hơn để giữ khả năng tương thích ngược mà chúng ta có thể làm với cách tiếp cận này, nó đang hoạt động cho trường hợp của tôi, hy vọng sẽ hiệu quả với bạn. Cũng khá dễ hiểu.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
    {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
    }

0
UIUserNotificationType types = UIUserNotificationTypeBadge |
    UIUserNotificationTypeSound | UIUserNotificationTypeAlert;

    UIUserNotificationSettings *mySettings =
    [UIUserNotificationSettings settingsForTypes:types categories:nil];

    [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];

    [application registerForRemoteNotifications];
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.