【问题标题】:Getting the MCC and MNC by means of CoreTelephony.framework private API in Objective-C在 Objective-C 中通过 CoreTelephony.framework 私有 API 获取 MCC 和 MNC
【发布时间】:2015-05-04 14:30:20
【问题描述】:

我需要获取当前国家/地区的MCCMNC 代码(不是来自 SIM 所在国家/地区的 CTCarrier 类)。

我为CoreTelephony.framework 使用私有API。在我的设备上一切正常。但是在方法CellMonitorCallback 中的其他设备上,我们获得cells = NULL

可能有人可以帮助我做错了什么?


#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  

【问题讨论】:

  • 它不再适用于 iOS 8.3。

标签: ios objective-c iphone-privateapi core-telephony


【解决方案1】:

我认为问题在于使用私有 api,因此您无法在非越狱手机上运行您的应用程序。我正在研究和你一样的东西,但有点晚了:) 我发现这个 answer 可以在 iOS 8.3 上运行,它说

从 iOS 8.3 开始,上述所有解决方案都需要授权才能工作

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

另外,这个project on github 只是我能找到的示例代码。

我想你已经知道答案了,但这可能对其他人有帮助,因为很难找到 :)

【讨论】:

  • 有很多私有 API 可以在未越狱的手机上运行(这也是 Apple 审查提交到应用商店的应用的原因之一)。或许您应该更详细地说明这一点(例如,一些私有 API 依赖于沙盒被破坏等)。
【解决方案2】:

从 iOS 8.3 开始,上述所有解决方案都需要授权才能工作

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

确实,据说上面提到的代码可以在ios 8.3及更高版本上运行以获取lac和cell。但是我真的不知道如何在越狱手机上插入上述内容。任何人都可以提供任何详细信息。或者有人这样测试吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多