---------------- код -----------------

ющая строка кода - это то, где наше приложение внезапно начало падать на iOS 11 / 11.0.1 / 11.0.2 / 11.1.1 / 11.2.2 для некоторых пользователей:

UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

У нас есть это вdidFinishLaunchingWithOptions, В отчете о сбое говорится:

Fatal Exception: NSInternalInconsistencyException
Invalid parameter not satisfying: bundleProxy != nil

Fatal Exception: NSInternalInconsistencyException
0  CoreFoundation                 0x1869b3d38 __exceptionPreprocess
1  libobjc.A.dylib                0x185ec8528 objc_exception_throw
2  CoreFoundation                 0x1869b3c0c +[NSException raise:format:]
3  Foundation                     0x187342c24 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
4  UserNotifications              0x18fcc973c -[UNUserNotificationCenter initWithBundleProxy:]
5  UserNotifications              0x18fcc950c __53+[UNUserNotificationCenter currentNotificationCenter]_block_invoke
6  libdispatch.dylib              0x186339048 _dispatch_client_callout
7  libdispatch.dylib              0x18633c710 dispatch_once_f$VARIANT$mp
8  UserNotifications              0x18fcc94ac +[UNUserNotificationCenter currentNotificationCenter]

Это явно исходит от iOS. Кто-нибудь еще испытывает ту же ошибку? Есть идеи, что происходит?

 Sam Jarman24 окт. 2017 г., 02:32
Вы поняли это?
 strangetimes26 окт. 2017 г., 13:06
Нет, все еще вижу таинственные сбои
 strangetimes29 мар. 2018 г., 17:28
@ SamJarman Я так думаю

Ответы на вопрос(2)

Решение Вопроса

что это будет работать для всех, однако я понял это для моего случая использования. Я создал фреймворк, который использовал приложение iOS. Эта структура использовалаUNUserNotificationCenter настроить оповещения. По какой-то причине кажется, что «комплект» не инициализируется правильно, когда этот код используется внутри фреймворка. Иногда это работает, иногда нет. ЭтотbundleProxyСудя по всему, это своего рода прокси, на который опирается инфраструктура уведомлений. Поскольку код выполняется изнутри фреймворка, возможно, этот пакет не найден во время выполнения, и система возвращает nil. У меня была эта проблема в целом при попытке загрузить ресурсы из Framework, где расположение пакета не является правильным.

В любом случае, решение для меня было хранить ссылку на[UNUserNotificationCenter currentNotificationCenter] в делегате приложения при запуске, а затем передайте его любому методу, который хотел его использовать. К тому времени, когда приложение закончило запуск, этоproxy Кажется, загружается правильно, если вызывающий код является двоичным файлом самого приложения. Это, кажется, исправило это для меня.

 strangetimes23 янв. 2019 г., 12:11
Нет, но, как объяснено, убедитесь, что ваш код не работает внутри фреймворка. Если это так, вам нужно передать ссылку от представителя вашего приложения.
 angusc23 янв. 2019 г., 11:15
Я сталкиваюсь с той же проблемой с bundleProxy! = Nil Ошибка проверки. Вызывающий его вызов - это UNUserNotificationCenter.current () в AppDelegate.didFinishLaunching, который, по-видимому, и является тем, что вы предлагаете. Можете ли вы опубликовать свой код, который работает?
 angusc23 янв. 2019 г., 12:58
Он находится в платформе, и в делегате приложения я пытался получить UNUserNotificationCenter.current (), но вызов не удался.

[UNUserNotificationCenter currentNotificationCenter] сбой иногда?

Согласно трассировке стека сбоев, bundleIdentifier равен нулю в частном методе инициализации UNUserNotificationCenter, и возникает исключение. Я не знаю почему.

К сожалению, метод вызывается вdispatch_once контекст, поэтому мы не можем воспроизвести этот сбой легко. Во-первых, я попытался использовать метод NSBundle:NSBundle.mainBundle.bundleIdentifier, но это не удалось. Я предполагаю, что система не использовала этот метод для получения bundleIdentifier, поэтому я попытался использовать частный метод инициализации UNUserNotificationCenterinitWithBundleIdentifier:(String)Worked он работал и пытался передать ноль этому методу, который вызывал сбой 100% времени !!!! Таким образом, мы можем использовать этот метод при загрузке файла и вернуть nil, еслиbundleIdentifier==nil, Я надеюсь, это поможет вам.

---------------- код -----------------

    /* UNUserNotificationCenter + Hack */
@implementation UNUserNotificationCenter (Hack)

+ (void)load {
    static dispatch_once_t _onceToken;
    dispatch_once(&_onceToken, ^{
        [self safeHook];
    });
}

+ (void)safeHook {

    /*hook UNUserNotificationCenter's systemMethod initWithBundleIdentifier:*/
    /* private method mix,hope no runtime check */
    NSString * orig_initWithBundleSelectorName = [NSString stringWithFormat:@"%@%@%@",@"initWi",@"thBundleId",@"entifier:"];

    SEL orig_initWithBundleSelector = NSSelectorFromString(orig_initWithBundleSelectorName);

    if (![self instancesRespondToSelector:orig_initWithBundleSelector]) {
        return;
    }

    SEL alt_initWithBundleSelector = @selector(ht_initWithBundleIdentifier:);
    Method origMethod = class_getInstanceMethod(self, orig_initWithBundleSelector);
    Method altMethod = class_getInstanceMethod(self, @selector(ht_initWithBundleIdentifier:));

    class_addMethod(self,
                    orig_initWithBundleSelector,
                    class_getMethodImplementation(self, orig_initWithBundleSelector),
                    method_getTypeEncoding(origMethod));
    class_addMethod(self,
                    alt_initWithBundleSelector,
                    class_getMethodImplementation(self, alt_initWithBundleSelector),
                    method_getTypeEncoding(altMethod));

    method_exchangeImplementations(origMethod, altMethod);
}

- (instancetype)ht_initWithBundleIdentifier:(id)identifier {

    if (nil==identifier||NSNull.null==identifier) {
        return nil;
    }
    /* you can test, if give nil to this method ,100% crash!!!!*/
    /* [self ht_initWithBundleIdentifier:nil] 100% crash!!!!*/
    return [self ht_initWithBundleIdentifier:identifier];
}

@end

Ваш ответ на вопрос