2015-05-04 16 views
5

Ich brauche MCC und MNC Code für das aktuelle Land (nicht aus der Klasse CTCarrier für das SIM-Heimatland).Holen der MCC und MNC über CoreTelephony.framework private API in Objective-C

Ich verwende private API für CoreTelephony.framework. Auf meinem Gerät funktioniert alles einwandfrei. Aber auf den anderen Geräten in der Methode CellMonitorCallback erhalten wir cells = NULL.

Kann jemand helfen, was ich falsch gemacht habe?


#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

Es funktioniert nicht mehr auf iOS 8.3. – pteofil

Antwort

1

Ich denke, das Problem Privat api verwendet, so dass Sie nicht Ihre Anwendung auf nicht Jailbreak-Handys laufen. Ich bin die Sache genauso Sie forschen aber ein wenig zu spät :) und ich fand dieses answer auf iOS 8.3 arbeiten, heißt es

Ab iOS 8.3 alle oben genannten Lösungen Anspruchs erfordern

zu arbeiten

Auch dieses project on github ist nur Beispielcode für mich, den ich finden kann.

Ich glaube, Sie bereits wissen, beantworten aber das kann hilft jemand anderes, weil es schwer ist :)

+0

Es gibt viele private APIs, die auf nicht-jailbroken Telefonen funktionieren (das ist einer der Gründe, warum Apple Apps überprüft, die an den App Store gesendet wurden). Vielleicht sollten Sie mehr zu diesem Punkt ausführen (z. B. einige private APIs sind darauf angewiesen, dass Sandboxing kompromittiert wird usw.). –

0

Ab iOS 8.3 alle oben genannten Lösungen Anspruch

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

Tatsächlich arbeiten erfordern zu finden, tha über code erwähnt wird gesagt, dass ausgeführt werden kann, um die lac und cell auf ios 8.3 und höher zu erhalten. Aber ich weiß wirklich nicht, wie man das obige auf ein jailbroken Telefon einfügt. Könnte jemand irgendwelche Detailinformationen geben. Oder jemand testet so?