2014-08-14 2 views
10

У меня есть следующий код в моем приложении - и я вижу некоторые сбои на iOS 7 в строке с комментарием.#ifdef __IPHONE_8_0 код работает также на iOS 7

+ (void)registerDeviceForRemoteNotifications { 
#if !TARGET_IPHONE_SIMULATOR 
    if ([[KOAAuthenticator sharedAuthenticator] currentUser] != nil) { 
     UIApplication *sharedApplication = [UIApplication sharedApplication]; 
#ifdef __IPHONE_8_0 
     [sharedApplication registerForRemoteNotifications]; // <--- CRASH HERE 
#else 
     [sharedApplication registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert]; 
#endif 
    } 
#endif 
} 

Crashlytics говорит: -[UIApplication registerForRemoteNotifications]: unrecognized selector sent to instance 0x157d04290

, как это вообще возможно? Этот код нельзя вызывать на iOS 7, верно?

EDIT: решение

+ (void)registerDeviceForRemoteNotifications { 
#if !TARGET_IPHONE_SIMULATOR 
    if ([[KOAAuthenticator sharedAuthenticator] currentUser] != nil) { 

     UIApplication *sharedApplication = [UIApplication sharedApplication]; 

#ifdef __IPHONE_8_0 
     if ([sharedApplication respondsToSelector:@selector(registerForRemoteNotifications)]) { 
      [sharedApplication registerForRemoteNotifications]; 
     } else { 
      [sharedApplication registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert]; 
     } 
#else 
     [sharedApplication registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert]; 
#endif 

    } 
#endif 
} 
+0

_compiler time_ и _runtime_ две разные вещи ... – holex

+0

я знаю; но я предполагаю, что это должно сработать - на iOS 8 и более поздних версиях '' 'registerForRemoteNotifications''', иначе' 'registerForRemoteNotificationTypes''' - правильно? – swalkner

+2

№. это решение принято в _compiler time_. если базовый SDK iOS8, то этот метод будет скомпилирован в ваш двоичный файл: '-registerForRemoteNotifications', если базовый SDK iOS7, то он будет скомпилирован в ваш двоичный файл:' -registerForRemoteNotificationTypes: '. в этом случае неуместно, что среда _runtime_ будет позже, потому что макросы являются функциями _complier time_, они вообще не связаны с _runtime_ на любом уровне. – holex

ответ

15

Ваш код добавляет поддержку только для компиляции на более раннюю версию Xcode и iOS SDK.

Вы должны добавить следующие проверки во время выполнения:

+0

Возможно, вы захотите изменить #else на #endif, чтобы сохранить код для вызова старого метода даже при создании нового SDK. (Текущий код не будет компилироваться.) – mstorsjo

+0

Я добавил решение своего ответа; должно быть так, так? – swalkner

+0

@mstorsjo Упс исправится. –

5

IFDEF оцениваются во время компиляции (или, скорее, предварительная обработка) время, а не во время выполнения, поэтому, который один из двух registerForRemoteNotifications вызовов получает включен в бинарнике только зависит от того, SDK, с которым вы строите, а не то, на каком устройстве оно работает.

+0

Извините, я отредактировал ваше сообщение по ошибке. –