CoreTelephony因原因崩溃:收到没有通知名称的通知

时间:2016-07-18 10:42:46

标签: ios iphone crash reachability core-telephony

我每天收到大约5,000个报告的问题“每天收到一条没有通知名称的通知”。

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException'  reason: 'Received a notification with no notification name'

Last Exception Backtrace:
0   CoreFoundation                      0x000000018206e950 __exceptionPreprocess + 132
1   libobjc.A.dylib                     0x000000018e5741fc objc_exception_throw + 60
2   CoreFoundation                      0x000000018206e810 +[NSException raise:format:arguments:] + 116
3   Foundation                          0x0000000182ba6db4 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 112
4   CoreTelephony                       0x00000001827ca39c -[CTTelephonyNetworkInfo handleNotificationFromConnection:ofType:withInfo:] + 272
5   CoreTelephony                       0x00000001827c9784 _ServerConnectionCallback(__CTServerConnection*, __CFString const*, __CFDictionary const*, void*) + 152
6   CoreTelephony                       0x00000001827de958 ___ZNK13CTServerState21sendNotification_syncE7CTEventPK10__CFStringPK14__CFDictionary_block_invoke15 + 32
7   libdispatch.dylib                   0x000000018eb4c014 _dispatch_call_block_and_release + 24
8   libdispatch.dylib                   0x000000018eb4bfd4 _dispatch_client_callout + 16
9   libdispatch.dylib                   0x000000018eb524a8 _dispatch_queue_drain + 640
10  libdispatch.dylib                   0x000000018eb4e4c0 _dispatch_queue_invoke + 68
11  libdispatch.dylib                   0x000000018eb530f4 _dispatch_root_queue_drain + 104
12  libdispatch.dylib                   0x000000018eb534fc _dispatch_worker_thread2 + 76
13  libsystem_pthread.dylib             0x000000018ece16bc _pthread_wqthread + 356
14  libsystem_pthread.dylib             0x000000018ece154c start_wqthread + 4

我发现了所有CoreTelephony通知并尝试重现该问题但失败了。

    /* For use with the CoreTelephony notification system. */
    extern CFStringRef kCTRegistrationStatusChangedNotification;
    extern CFStringRef kCTRegistrationStateDurationReportNotification;
    extern CFStringRef kCTRegistrationServiceProviderNameChangedNotification;
    extern CFStringRef kCTRegistrationOperatorNameChangedNotification;
    extern CFStringRef kCTRegistrationNewServingNetworkNotification;
    extern CFStringRef kCTRegistrationDataStatusChangedNotification;
    extern CFStringRef kCTRegistrationDataActivateFailedNotification;
    extern CFStringRef kCTRegistrationCellularDataPlanHideIndicatorNotification;
    extern CFStringRef kCTRegistrationCellularDataPlanActivateFailedNotification;
    extern CFStringRef kCTRegistrationCustomerServiceProfileUpdateNotification;
    extern CFStringRef kCTRegistrationCellChangedNotification;
    extern CFStringRef kCTRegistrationCauseCodeNotification;

为什么我会崩溃? 我怎样才能更改我的代码,以便我不再遇到这个问题? 任何帮助都非常感谢。

修改

我正在使用Reachability类(https://github.com/tonymillion/Reachability)来检测网络类型。

+ (NSString *)networkName
 {    
    Reachability *reach = [Reachability reachabilityForInternetConnection];
    [reach startNotifier];

    NetworkStatus networkStatus = [reach currentReachabilityStatus];
    CTTelephonyNetworkInfo *telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];

    if (networkStatus == ReachableViaWiFi) {
        return @"WIFI";
    } else if (networkStatus == ReachableViaWWAN) {
        if ([telephonyInfo respondsToSelector:@selector(currentRadioAccessTechnology)]) { 
            if ([[telephonyInfo currentRadioAccessTechnology] isEqualToString:CTRadioAccessTechnologyGPRS]) {
                return @"GPRS";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyEdge]) {
                return @"EDGE";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyWCDMA]) {
                return @"WCDMA";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyHSDPA]) {
                return @"HSDPA";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyHSUPA]) {
                return @"HSUPA";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyCDMA1x]) {
                return @"CDMA1X";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) {
                return @"CDMAEVDOREV0";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) {
                return @"CDMAEVDOREVA";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) {
                return @"CDMAEVDOREVB";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyeHRPD]) {
                return @"HRPD";
            } else if ([[telephonyInfo currentRadioAccessTechnology]  isEqualToString:CTRadioAccessTechnologyLTE]) {
                return @"LTE";
            }
            return @"UNKNOWN";
        } else {
            return @"WWAN";
        }
    } else {
        return @"NotReachable";
    }
}

2 个答案:

答案 0 :(得分:1)

我想知道这是否与使用旧版TestFlight的this similar issue相关:

  

有一个iOS错误导致CTTelephonyNetworkInfo类的实例有时会在取消分配后收到通知。不是实例化,使用和释放实例,而是必须保留并永远不释放它们以解决错误。

这就像你的回溯看起来像一个僵尸。为什么不尝试使用永远不会按照链接问题中的建议发布的CTTelephonyNetworkInfo静态实例?

@import CoreTelephony;

// ...

static CTTelephonyNetworkInfo *netInfo;
static dispatch_once_t dispatchToken;
if (!netInfo) {
    dispatch_once(&dispatchToken, ^{
        netInfo = [[CTTelephonyNetworkInfo alloc] init];
    });
}

答案 1 :(得分:0)

要解决此问题,我会使用方法调整来重新路由最初发送到-[CTTelephonyNetworkInfo handleNotificationFromConnection:ofType:withInfo:]的所有来电。
它工作正常。

#import <CoreTelephony/CTTelephonyNetworkInfo.h>

struct __CTServerConnection {
    int a;
    int b;
    CFMachPortRef myport;
    int c;
    int d;
    int e;
    int f;
    int g;
    int h;
    int i;
};

typedef struct __CTServerConnection CTServerConnection;
typedef CTServerConnection* CTServerConnectionRef;


@implementation CTTelephonyNetworkInfo (Fixed)

- (void)fixed_handleNotificationFromConnection:(CTServerConnectionRef)connection
                                        ofType:(NSString *)notificationName
                                      withInfo:(NSDictionary *)info
{
    if ([notificationName length]) {
        return [self fixed_handleNotificationFromConnection:connection
                                                     ofType:notificationName
                                                   withInfo:info];
    }
}