2015-05-04 230 views
5

我需要獲取MCCMNC代碼爲當前國家(而不是來自SIM卡國家的CTCarrier類)。我使用私人API CoreTelephony.framework。在我的設備上,所有的作品都正確但是在方法CellMonitorCallback的其他設備上,我們獲得了cells = NULL通過CoreTelephony.framework私人API獲取MCC和MNC Objective-C

可能有人可以幫助我做錯了什麼?


#import "AMCoreTelephone.h" 
#import <CoreTelephony/CTCarrier.h> 
#import <CoreTelephony/CTTelephonyNetworkInfo.h> 

struct CTResult 
{ 
    int flag; 
    int a; 
}; 

extern CFStringRef const kCTCellMonitorCellType; 
extern CFStringRef const kCTCellMonitorCellTypeServing; 
extern CFStringRef const kCTCellMonitorCellTypeNeighbor; 
extern CFStringRef const kCTCellMonitorCellId; 
extern CFStringRef const kCTCellMonitorLAC; 
extern CFStringRef const kCTCellMonitorMCC; 
extern CFStringRef const kCTCellMonitorMNC; 
extern CFStringRef const kCTCellMonitorUpdateNotification; 

id _CTServerConnectionCreate(CFAllocatorRef, void*, int*); 
void _CTServerConnectionAddToRunLoop(id, CFRunLoopRef, CFStringRef); 
mach_port_t _CTServerConnectionGetPort(id); 

#ifdef __LP64__ 
void _CTServerConnectionRegisterCallService(id); 
void _CTServerConnectionUnregisterCallService(id,int*); 
void _CTServerConnectionRegisterForNotification(id, CFStringRef); 
void _CTServerConnectionCellMonitorStart(id); 
void _CTServerConnectionCellMonitorStop(id); 
void _CTServerConnectionCellMonitorCopyCellInfo(id, void*, CFArrayRef*); 
void _CTServerConnectionIsInHomeCountry(id, void*, int*); 
void _CTServerConnectionCopyCountryCode(id, void*, CFStringRef); 

#else 

void _CTServerConnectionRegisterCallService(struct CTResult*, id); 
#define _CTServerConnectionRegisterCallService(connection) { struct CTResult res; _CTServerConnectionRegisterCallService(&res, connection); } 

void _CTServerConnectionRegisterForNotification(struct CTResult*, id, CFStringRef); 
#define _CTServerConnectionRegisterForNotification(connection, notification) { struct CTResult res; _CTServerConnectionRegisterForNotification(&res, connection, notification); } 

void _CTServerConnectionCellMonitorStart(struct CTResult*, id); 
#define _CTServerConnectionCellMonitorStart(connection) { struct CTResult res; _CTServerConnectionCellMonitorStart(&res, connection); } 

void _CTServerConnectionCellMonitorStop(struct CTResult*, id); 
#define _CTServerConnectionCellMonitorStop(connection) { struct CTResult res; _CTServerConnectionCellMonitorStop(&res, connection); } 

void _CTServerConnectionCellMonitorCopyCellInfo(struct CTResult*, id, void*, CFArrayRef*); 
#define _CTServerConnectionCellMonitorCopyCellInfo(connection, tmp, cells) { struct CTResult res; _CTServerConnectionCellMonitorCopyCellInfo(&res, connection, tmp, cells); } 

void _CTServerConnectionIsInHomeCountry(struct CTResult*, id, int*); 
#define CTServerConnectionIsInHomeCountry(connection, isHomeCountry) { struct CTResult res; _CTServerConnectionIsInHomeCountry(&res, connection, &isHomeCountry); } 

#endif 


@implementation AMCoreTelephone 
{ 
    CTCarrier *_carrier; 
    id CTConnection; 
    mach_port_t port; 
} 

+ (instancetype) sharedInstance 
{ 
    static AMCoreTelephone *instance; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     instance = [[AMCoreTelephone alloc] init_true]; 
    }); 
    return instance; 
} 

- (instancetype) init_true 
{ 
    if (self = [super init]) { 
     _carrier = [[CTTelephonyNetworkInfo new] subscriberCellularProvider]; 
    } 
    return self; 
} 


- (void) startMonitoring{ 
    #if TARGET_IPHONE_SIMULATOR 
     return; 
    #else 
     CTConnection = _CTServerConnectionCreate(kCFAllocatorDefault, CellMonitorCallback, NULL); 
     _CTServerConnectionRegisterForNotification(CTConnection, kCTCellMonitorUpdateNotification); 

     port = _CTServerConnectionGetPort(CTConnection); 
     CFMachPortRef ref = CFMachPortCreateWithPort(kCFAllocatorDefault,port,NULL,NULL, NULL); 
     CFRunLoopSourceRef rlref = CFMachPortCreateRunLoopSource (kCFAllocatorDefault, ref, 0); 
     CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent(); 
     CFRunLoopAddSource(currentRunLoop, rlref, kCFRunLoopCommonModes); 

     _CTServerConnectionCellMonitorStart(CTConnection); 

    #endif 

} 

- (void) stopMonitoring{ 
    _CTServerConnectionCellMonitorStop(CTConnection); 
} 


int CellMonitorCallback(id connection, CFStringRef string, CFDictionaryRef dictionary, void *data) 
{ 
    int tmp = 0; 
    CFArrayRef cells = NULL; 
    _CTServerConnectionCellMonitorCopyCellInfo(connection, (void*)&tmp, &cells); 
    if (cells == NULL) 
    { 
     return 0; 
    } 

    for (NSDictionary* cell in (__bridge NSArray*)cells) 
    { 
     int LAC, CID, MCC, MNC; 

     if ([cell[(__bridge NSString*)kCTCellMonitorCellType] isEqualToString:(__bridge NSString*)kCTCellMonitorCellTypeServing]) 
     { 
      LAC = [cell[(__bridge NSString*)kCTCellMonitorLAC] intValue]; 
      CID = [cell[(__bridge NSString*)kCTCellMonitorCellId] intValue]; 
      MCC = [cell[(__bridge NSString*)kCTCellMonitorMCC] intValue]; 
      MNC = [cell[(__bridge NSString*)kCTCellMonitorMNC] intValue]; 
     } 
     else if ([cell[(__bridge NSString*)kCTCellMonitorCellType] isEqualToString:(__bridge NSString*)kCTCellMonitorCellTypeNeighbor]) 
     { 
     } 
    } 

    CFRelease(cells); 

    return 0; 
} 

@end 
+0

它不再適用於iOS 8.3。 – pteofil

回答

1

我認爲這個問題是使用私有API,所以你不能運行在非越獄的手機應用程序。我研究的東西是相同的,但你有點晚了:)我發現這個answer在iOS 8.3工作,它說

隨着iOS 8.3版本以上所有的解決方案都需要授權工作

<key>com.apple.CommCenter.fine-grained</key> 
<array> 
    <string>spi</string> 
</array> 

此外project on github只是我可以找到的示例代碼。

我想你已經知道答案,但是這可能幫助別人,因爲它很難找到:)

+0

在非越獄手機上有很多私人API可用(這是Apple評論提交給應用商店的應用程序的原因之一)。也許你應該更詳細地闡述這一點(例如,_some_私有API依賴於沙箱被入侵等)。 –

0

隨着iOS 8.3版本以上所有的解決方案都需要授權工作

<key>com.apple.CommCenter.fine-grained</key> 
<array> 
    <string>spi</string> 
</array> 

事實上,上面提到的代碼據說可以在ios 8.3和更高版本上運行以獲取lac和cell。但我真的不知道如何將上述內容插入越獄手機。有誰可以提供任何詳細信息。或者任何人測試這種方式?

相關問題