programing

registerForRemoteNotification타입: iOS 8.0 이후에서는 지원되지 않습니다.

mailnote 2023. 4. 11. 22:20
반응형

registerForRemoteNotification타입: iOS 8.0 이후에서는 지원되지 않습니다.

iOS 8.x에서 푸시 알림을 등록하려고 할 때:

application.registerForRemoteNotificationTypes(UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound)

다음의 에러가 표시됩니다.

registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later.

새로운 방법이 뭔지 생각나는 거 없어?iOS 7.x에서 Swift 앱을 실행하면 동작합니다.

편집

iOS 7.x에서는 조건 코드를 포함하면 얻을 수 있습니다(SystemVersion 조건부 또는 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000).

dyld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings

iOS용 <10>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    //-- Set Notification
    if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) 
    {
           // iOS 8 Notifications
           [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

           [application registerForRemoteNotifications];
    }
    else
    {
          // iOS < 8 Notifications
          [application registerForRemoteNotificationTypes:
                     (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
    }

     //--- your custom code
     return YES;
}

iOS10의 경우

https://stackoverflow.com/a/39383027/3560390

설명한 바와 같이 iOS 버전별로 다른 방법을 사용해야 합니다.팀이 Xcode 5(iOS 8 셀렉터에 대해 알지 못함)와 Xcode 6을 모두 사용하는 경우 다음과 같이 조건부 컴파일을 사용해야 합니다.

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    // use registerUserNotificationSettings
} else {
    // use registerForRemoteNotificationTypes:
}
#else
// use registerForRemoteNotificationTypes:
#endif

Xcode 6 만을 사용하고 있는 경우는, 다음의 순서에 따릅니다.

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    // use registerUserNotificationSettings
} else {
    // use registerForRemoteNotificationTypes:
}

에서 알림 입니다.UserNotification는 리모트 또는 로컬에서 사용자에게 표시되는 메시지입니다.허락을 받아야 보여줄 수 있어요.이는 WWDC 2014 비디오 "iOS 알림의 새로운 기능"에 설명되어 있습니다.

@Prasath의 답변을 기반으로 합니다.Swift에서는 다음과 같이 합니다.

if application.respondsToSelector("isRegisteredForRemoteNotifications")
{
    // iOS 8 Notifications
    application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: (.Badge | .Sound | .Alert), categories: nil));
    application.registerForRemoteNotifications()
}
else
{
    // iOS < 8 Notifications
    application.registerForRemoteNotificationTypes(.Badge | .Sound | .Alert)
}

iOS 8은 알림 등록을 역호환되지 않는 방식으로 변경했습니다.iOS 7과 8을 지원해야 하지만(8 SDK로 빌드된 앱은 허용되지 않음) 필요한 셀렉터를 확인하고 실행 중인 버전에 대해 조건부로 올바르게 호출할 수 있습니다.

여기 UIApplication에 관한 카테고리가 있습니다.이 카테고리는 Xcode 5와 Xcode 6 모두에서 동작하는 깨끗한 인터페이스 뒤에 이 논리를 숨깁니다.

머리글:

//Call these from your application code for both iOS 7 and 8
//put this in the public header
@interface UIApplication (RemoteNotifications)

- (BOOL)pushNotificationsEnabled;
- (void)registerForPushNotifications;

@end

구현:

//these declarations are to quiet the compiler when using 7.x SDK
//put this interface in the implementation file of this category, so they are
//not visible to any other code.
@interface NSObject (IOS8)

- (BOOL)isRegisteredForRemoteNotifications;
- (void)registerForRemoteNotifications;

+ (id)settingsForTypes:(NSUInteger)types categories:(NSSet*)categories;
- (void)registerUserNotificationSettings:(id)settings;

@end

@implementation UIApplication (RemoteNotifications)

- (BOOL)pushNotificationsEnabled
{
    if ([self respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
    {
        return [self isRegisteredForRemoteNotifications];
    }
    else
    {
        return ([self enabledRemoteNotificationTypes] & UIRemoteNotificationTypeAlert);
    }
}

- (void)registerForPushNotifications
{
    if ([self respondsToSelector:@selector(registerForRemoteNotifications)])
    {
        [self registerForRemoteNotifications];

        Class uiUserNotificationSettings = NSClassFromString(@"UIUserNotificationSettings");

        //If you want to add other capabilities than just banner alerts, you'll need to grab their declarations from the iOS 8 SDK and define them in the same way.
        NSUInteger UIUserNotificationTypeAlert   = 1 << 2;

        id settings = [uiUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:[NSSet set]];            
        [self registerUserNotificationSettings:settings];

    }
    else
    {
        [self registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert];
    }
}

@end

이 방법으로 하면 하위 호환성을 유지할 수 있는 더 좋은 방법이라고 생각합니다.이 방법은 제 케이스에 유효하며, 고객님께도 도움이 될 것입니다.또한 꽤 이해하기 쉽습니다.

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

Swift에 관심이 있는 경우:

if let registration: AnyObject = NSClassFromString("UIUserNotificationSettings") { // iOS 8+
    let notificationTypes: UIUserNotificationType = (.Alert | .Badge | .Sound)
    let notificationSettings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)

    application.registerUserNotificationSettings(notificationSettings)
} else { // iOS 7
    application.registerForRemoteNotificationTypes(.Alert | .Badge | .Sound)
}

「카테고리」의 NSSet 변수를 어떻게 설정할지를 알 수 없었기 때문에, 누군가 기입해 주신다면, 기꺼이 이 투고를 편집하겠습니다.그러나 푸시 알림 대화 상자가 나타납니다.

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

편집: 이 코드를 사용하여 휴대폰으로 전송하라는 푸시 알림을 받았기 때문에 카테고리 파라미터가 필요한지 잘 모르겠습니다.

AnyObject는 id의 정신적 후계자이므로 AnyObject에서 원하는 메시지를 호출할 수 있습니다.이는 id에게 메시지를 보내는 것과 같습니다.그래, 좋아.그러나 이제 AnyObject에서 모든 메서드는 옵션이며 작업할 수 있는 기능이 있다는 개념을 추가했습니다.

이상, 저는 UIAppplication을 캐스팅할 수 있기를 희망했습니다.shared Application()을 AnyObject로 전송한 후 메서드시그니처와 동일한 변수를 만들고 해당 변수를 임의 메서드로 설정한 후 변수를 테스트합니다.이건 효과가 없는 것 같았어.컴파일러는 iOS 8.0 SDK에 대해 컴파일 할 때 그 메서드가 어디에 있어야 하는지 알고 있기 때문에 이 모든 것을 메모리 룩업으로 최적화할 수 있습니다.변수를 테스트하고 EXC_B를 얻을 때까지 모든 것이 정상적으로 작동합니다.AD_ACCESS.

그러나 모든 메서드가 옵션이라는 것을 알게 된 같은 WWDC 토크에서는 옵션 체인을 사용하여 옵션 메서드를 호출합니다.이것이 효과가 있는 것 같습니다.이 메서드가 존재하는지 확인하기 위해서는 실제로 호출을 시도해야 합니다.이는 UIUserNotificationSettings 개체를 만들기 전에 이 메서드가 존재하는지 확인하려고 하기 때문에 알림 등록 시 문제가 됩니다.이 메서드를 제로라고 불러도 괜찮을 것 같기 때문에, 나에게 있어서 유효한 솔루션은 다음과 같습니다.

var ao: AnyObject = UIApplication.sharedApplication()
if let x:Void = ao.registerUserNotificationSettings?(nil) {
    // It's iOS 8
    var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
    var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
    UIApplication.sharedApplication().registerUserNotificationSettings(settings)
} else {
    // It's older
    var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
    UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
}

이와 관련하여 많은 검색 후, 이 WWDC 토크 https://developer.apple.com/videos/wwdc/2014/ #407에서 "프로토콜의 옵션 메서드"에 대한 정보를 얻었습니다.

Xcode 6.1 베타에서는 위의 코드가 더 이상 작동하지 않으며 아래 코드가 작동합니다.

   if UIApplication.sharedApplication().respondsToSelector("registerUserNotificationSettings:") {
        // It's iOS 8
        var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
       var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
       UIApplication.sharedApplication().registerUserNotificationSettings(settings)
    } else {
        // It's older
        var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
        UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
    }

IOS7 IOS8에 지원을 추가할 경우 이 코드를 프로젝트에 적용할 수 있습니다.

-(void) Subscribe {
    NSLog(@"Registering for push notifications...");

    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    }
}

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

    if (notificationSettings.types) {
        NSLog(@"user allowed notifications");
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        NSLog(@"user did not allow notifications");
        UIAlertView *alert =[[UIAlertView alloc] 
            initWithTitle:@"Please turn on Notification"
            message:@"Go to Settings > Notifications > App.\n Switch on Sound, Badge & Alert"
            delegate:self
            cancelButtonTitle:@"Ok"
            otherButtonTitles: nil];
        [alert show];
        // show alert here
    }
}

Xcode 6.1 베타 버전이 작동한 후 6.1 베타 버전(이전 베타 버전)에서 작동을 멈춘 Tom S 코드를 약간 편집합니다.

   if UIApplication.sharedApplication().respondsToSelector("registerUserNotificationSettings:") {
        // It's iOS 8
        var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
       var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
       UIApplication.sharedApplication().registerUserNotificationSettings(settings)
    } else {
        // It's older
        var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
        UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
    }

이거 써도 돼

if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) 
    {
        // for iOS 8
        [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

        [application registerForRemoteNotifications];
    }
    else
    {
        // for iOS < 8
        [application registerForRemoteNotificationTypes:
         (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
    }

    // RESET THE BADGE COUNT 
    application.applicationIconBadgeNumber = 0;

Swift 2.0

// Checking if app is running iOS 8
    if application.respondsToSelector("isRegisteredForRemoteNotifications") {

        print("registerApplicationForPushNotifications - iOS 8")

        application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil));
        application.registerForRemoteNotifications()

    } else {
        // Register for Push Notifications before iOS 8
        print("registerApplicationForPushNotifications - <iOS 8")
        application.registerForRemoteNotificationTypes([UIRemoteNotificationType.Alert, UIRemoteNotificationType.Badge, UIRemoteNotificationType.Sound])

    }

ios 8 코드만 있으면 됩니다.

 - (BOOL)application:(UIApplication *)application       didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
       [application registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound  | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)  categories:nil]];

       [application registerForRemoteNotifications];
}

 return YES;
}

이게 내가 하는 일이 더 깔끔하고 잘 되는 방법이야.

if (floor(NSFoundationVersionNumber) < NSFoundationVersionNumber_iOS_8_0)
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|
     UIRemoteNotificationTypeAlert| UIRemoteNotificationTypeSound];
     else {
         [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; 
         [application registerForRemoteNotifications];
     }

iOS 8 이상용

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

언급URL : https://stackoverflow.com/questions/24454033/registerforremotenotificationtypes-is-not-supported-in-ios-8-0-and-later

반응형