iOS中获取MCC和MNC的方法及iOS 16中CTCarrier被弃用的替代方案

这篇具有很好参考价值的文章主要介绍了iOS中获取MCC和MNC的方法及iOS 16中CTCarrier被弃用的替代方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、使用公共API获取MCC和MNC

在iOS中,我们可以使用CoreTelephony框架来获取用户的移动国家代码(MCC)和移动网络代码(MNC)。具体操作步骤如下:

  1. 在Xcode项目中,点击项目目标,进入“General”选项卡,在“Frameworks, Libraries, and Embedded Content”下点击“+”按钮,搜索并添加CoreTelephony.framework

  2. 在需要获取MCC和MNC信息的Swift文件顶部导入CoreTelephony框架:

import CoreTelephony
  1. 创建一个CTTelephonyNetworkInfo实例:
let networkInfo = CTTelephonyNetworkInfo()
  1. 使用CTTelephonyNetworkInfo实例的serviceSubscriberCellularProviders属性获取包含CTCarrier对象的字典。字典中的每个键都对应用户设备中的一个运营商:
if let carrierInfo = networkInfo.serviceSubscriberCellularProviders {
    for (key, carrier) in carrierInfo {
        // 获取每个运营商的MCC和MNC
        let mobileCountryCode = carrier.mobileCountryCode
        let mobileNetworkCode = carrier.mobileNetworkCode

        print("Carrier: \(key), MCC: \(String(describing: mobileCountryCode)), MNC: \(String(describing: mobileNetworkCode))")
    }
}

CTCarrier实例的mobileCountryCodemobileNetworkCode属性将给出MCC和MNC值。需要注意的是,如果设备没有SIM卡、处于飞行模式或未连接到蜂窝网络,此方法可能返回nil。在应用程序中,应适当处理这些情况。

二、iOS 16中CTCarrier被弃用后的替代方案

根据Apple 开发者文档中描述,CTCarrier在iOS 16.0中会被取消。
经过了iOS16.1-iOS 16.4,这一天终于来了。新版本Xcode 14.3 打包,在iOS 16.4以上,CTCarrier的属性都被禁用了,直接返回65535或者- -

@available(iOS, introduced: 4.0, deprecated: 16.0, message: "Deprecated with no replacement")
open class CTCarrier : NSObject {

    
    /*
     * carrierName
     *
     * Discussion:
     *   An NSString containing the name of the subscriber's cellular service provider.
     */
    @available(iOS, introduced: 4.0, deprecated: 16.0, message: "Deprecated; returns '--' at some point in the future")
    open var carrierName: String? { get }

    
    /*
     * mobileCountryCode
     *
     * Discussion:
     *   An NSString containing the mobile country code for the subscriber's 
     *   cellular service provider, in its numeric representation
     */
    @available(iOS, introduced: 4.0, deprecated: 16.0, message: "Deprecated; returns '65535' at some point in the future")
    open var mobileCountryCode: String? { get }

    
    /*
     * mobileNetworkCode
     *
     * Discussion:
     *   An NSString containing the  mobile network code for the subscriber's 
     *   cellular service provider, in its numeric representation
     */
    @available(iOS, introduced: 4.0, deprecated: 16.0, message: "Deprecated; returns '65535' at some point in the future")
    open var mobileNetworkCode: String? { get }

    
    /*
     * isoCountryCode
     *
     * Discussion:
     *   Returns an NSString object that contains country code for
     *   the subscriber's cellular service provider, represented as an ISO 3166-1
     *   country code string
     */
    
    @available(iOS, introduced: 4.0, deprecated: 16.0, message: "Deprecated; returns '--' at some point in the future")
    open var isoCountryCode: String? { get }

    
    /*
     * allowsVOIP
     *
     * Discussion:
     *   A BOOL value that is YES if this carrier allows VOIP calls to be
     *   made on its network, NO otherwise.
     */
    
    @available(iOS, introduced: 4.0, deprecated: 16.0, message: "Deprecated; returns YES at some point in the future")
    open var allowsVOIP: Bool { get }
}

若要使用私有API,可以按照以下步骤操作:
(请注意,使用私有API可能导致应用被拒绝,且这些API可能在未来的iOS版本中发生变化或被移除。因此,在可能的情况下,最好依赖于公共API。)

API被弃用,苹果可能会提供替代的公共API。

要使用私有API,可以按照以下步骤操作:

  1. 首先,在Swift项目中创建一个桥接头文件,以便访问Objective-C函数。具体操作如下:
    a. File > New > File > Header File,将其命名为BridgingHeader.h
    b. 转到项目目标的Build Settings选项卡,搜索“Objective-C Bridging Header”并设置值为BridgingHeader.h文件的路径。路径应该类似于:$(PROJECT_DIR)/YourProjectName/BridgingHeader.h

  2. 将以下代码添加到BridgingHeader.h文件中,以暴露私有API:

#import <CoreTelephony/CoreTelephonyDefines.h>

__BEGIN_DECLS

extern NSString* const CTRadioAccessTechnologyDidChangeNotification;
extern NSString* const CTSubscriberInfo;

CFNotificationCenterRef _CTServerConnectionCreate(CFAllocatorRef, void(*)(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo), int*);
void _CTServerConnectionAddToRunLoop(CFNotificationCenterRef, CFRunLoopRef, CFStringRef);
void _CTServerConnectionSetTargetQueue(CFNotificationCenterRef, dispatch_queue_t);

CTTelephonyCenterAddObserver(id, CFNotificationCallback, CFStringRef, void *, CFNotificationSuspensionBehavior);

__END_DECLS
  1. 在Swift文件中导入CoreTelephony框架和桥接头文件:
import CoreTelephony
import Foundation
  1. 定义一个函数,当CTCarrier发生变化时将被调用:
func radioAccessTechnologyDidChange(notification: Notification) {
    if let userInfo = notification.userInfo as? [String: AnyObject],
       let servingCell = userInfo["kCTIndicatorsGradedServingCellDescription"] as? [String: AnyObject],
       let mcc = servingCell["MCC"] as? Int,
       let mnc = servingCell["MNC"] as? Int {
        print("MCC: \(mcc), MNC: \(mnc)")
    }
}
  1. 设置回调并为CTCarrier变化通知添加观察者:
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
let callback: CFNotificationCallback = { center, observer, name, object, userInfo in
    let notification = Notification(name: Notification.Name(rawValue: name! as String), object: nil, userInfo: userInfo as? [AnyHashable: Any])
    radioAccessTechnologyDidChange(notification: notification)
}

let notificationName = "kCTIndicatorsSignalStrengthNotification" as CFString
CFNotificationCenterAddObserver(notificationCenter, nil, callback, notificationName, nil, .deliverImmediately)

三、尝试混淆私有API获取

使用私有API时,为了规避App Store审核,可以尝试混淆私有API的调用。请注意,这种做法并不能保证你的应用能够通过审核,因为苹果可能会采用其他方法来检测私有API的使用。此外,依赖私有API可能导致应用在未来的iOS版本中出现兼容性问题。

以下是一个尝试混淆私有API调用的例子:

  1. 首先,确保已经按照前面的说明创建了一个桥接头文件(BridgingHeader.h)。

  2. BridgingHeader.h文件中,将私有API的声明改为动态获取。删除原有的私有API声明,并添加以下代码:

#import <CoreTelephony/CoreTelephonyDefines.h>

__BEGIN_DECLS

CFNotificationCenterRef (*_CTServerConnectionCreate)(CFAllocatorRef, void(*)(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo), int*);
void (*_CTServerConnectionAddToRunLoop)(CFNotificationCenterRef, CFRunLoopRef, CFStringRef);
void (*_CTServerConnectionSetTargetQueue)(CFNotificationCenterRef, dispatch_queue_t);

CTTelephonyCenterAddObserver(id, CFNotificationCallback, CFStringRef, void *, CFNotificationSuspensionBehavior);

__END_DECLS
  1. 在Swift文件中,使用动态库加载(dlopen)和符号查找(dlsym)来获取私有API的函数指针。确保已经导入了CoreTelephony框架和Foundation框架:
import CoreTelephony
import Foundation
  1. 实现一个方法来获取私有API的函数指针:
func getPrivateAPIFunctionPointers() {
    let coreTelephonyHandle = dlopen("/System/Library/Frameworks/CoreTelephony.framework/CoreTelephony", RTLD_LAZY)

    if coreTelephonyHandle != nil {
        let createFunction = dlsym(coreTelephonyHandle, "_CTServerConnectionCreate")
        let addToRunLoopFunction = dlsym(coreTelephonyHandle, "_CTServerConnectionAddToRunLoop")
        let setTargetQueueFunction = dlsym(coreTelephonyHandle, "_CTServerConnectionSetTargetQueue")

        _CTServerConnectionCreate = unsafeBitCast(createFunction, to: type(of: _CTServerConnectionCreate))
        _CTServerConnectionAddToRunLoop = unsafeBitCast(addToRunLoopFunction, to: type(of: _CTServerConnectionAddToRunLoop))
        _CTServerConnectionSetTargetQueue = unsafeBitCast(setTargetQueueFunction, to: type(of: _CTServerConnectionSetTargetQueue))

        dlclose(coreTelephonyHandle)
    }
}
  1. 在需要获取MCC和MNC的地方,调用getPrivateAPIFunctionPointers()方法来获取私有API的函数指针。然后按照之前的步骤设置回调和添加观察者。

请注意,尽管这种方法可以在一定程度上混淆私有API的使用,但无法保证应用能够通过App Store的审核。此外,依赖私有API可能导致应用在未来的iOS版本中出现兼容性问题。文章来源地址https://www.toymoban.com/news/detail-501826.html

到了这里,关于iOS中获取MCC和MNC的方法及iOS 16中CTCarrier被弃用的替代方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WebSecurityConfigurerAdapter被弃用Spring Security基于组件化的配置和使用

    在Spring Security 5.7及之后的版本中 WebSecurityConfigurerAdapter 将被启用,安全框架将转向基于组件的安全配置。 spring security官方文档 Spring Security without the WebSecurityConfigurerAdapter 如果使用的Spring Boot版本高于低于2.7.0、Spring Security版本高于5.7,就会出现如下的提示: 1、被启用的原因

    2024年02月02日
    浏览(32)
  • Android Handler被弃用,那么以后怎么使用Handler,或者类似的功能

    Android API30左右,Android应用在使用传统写法使用Handler类的时候会显示删除线,并提示相关的方法已经被弃用,不建议使用。 Android studio中的显示和建议: 看下官方API关于此处的解释:  简要说就是如果在实例化Handler的时候不提供Looper, 可能导致操作丢失(Handler 没有预估到新

    2023年04月21日
    浏览(32)
  • Unity打包APK错误:‘android.enableR8‘选项已被弃用,不应再使用

    Unity打包APK错误:\\\'android.enableR8’选项已被弃用,不应再使用 在Unity游戏开发中,我们经常需要将游戏打包成APK文件以在Android设备上进行测试或发布。然而,有时候在打包APK的过程中,可能会遇到一些错误。其中一个常见的错误是 “The option ‘android.enableR8’ is deprecated and sh

    2024年02月08日
    浏览(39)
  • Python错题集-7:DeprecationWarning: Conversion of an array with ndim(被弃用警告)

    DeprecationWarning: Conversion of an array with ndim 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)   X[i] = np.random.normal(loc=Ex, scale=np.abs(Enn), size=1) DeprecationWarning: Conversion of an array with ndim  是一个警告,通常出

    2024年04月09日
    浏览(33)
  • Elasticsearch RestHighLevelClient 已标记为被弃用 它的替代方案 Elasticsearch Java API Client 的基础教程及迁移方案

    在Elasticsearch7.15版本之后,Elasticsearch官方将它的高级客户端 RestHighLevelClient 标记为弃用状态。同时推出了全新的Java API客户端 Elasticsearch Java API Client ,该客户端也将在Elasticsearch8.0及以后版本中成为官方推荐使用的客户端。 Elasticsearch Java API Client 支持除 Vector tile search API 和

    2024年01月16日
    浏览(28)
  • Elasticsearch8.x版本中RestHighLevelClient被弃用,新版本中全新的Java客户端Elasticsearch Java API Client中常用API练习

    在Es7.15版本之后,es官方将它的高级客户端RestHighLevelClient标记为弃用状态。同时推出了全新的java API客户端Elasticsearch Java API Client,该客户端也将在Elasticsearch8.0及以后版本中成为官方推荐使用的客户端。 Elasticsearch Java API Client支持除Vector title search API和Find structure API之外的所有

    2023年04月08日
    浏览(32)
  • 升级iOS17后可以降级吗?iOS17退回iOS16方法教程分享

    iOS 17已上线几天,从网上用户的反馈和媒体机构的报告来看,iOS17系统对旧机型来说并不友好,除了电池续航下降以外,占用大量储存空间,BUG也不少。 苹果于 9 月 7 日发布了 iOS 16.6.1 版本,如果升级iOS17后发现不适合自己,可参考以下方法退回到iOS16.6.1。 降级工具小编推荐

    2024年02月08日
    浏览(34)
  • iOS16图标文字阴影如何去掉?分享阴影不显示的方法!

    更新到iOS16正式版的iPhone用户,发现继续使用自己喜欢的浅色壁纸时, 每个APP图标下方文字都出现了阴影 。 如上图中所示,iOS16的图标文字阴影,应该是苹果开发为了在 浅色背景下凸出APP名称 而设计的。但部分iPhone用户纷纷表示,这样的UI设计确实无法接受。 iOS16浅色壁纸

    2024年01月21日
    浏览(30)
  • iOS性能测试方法-获取手机内存数据

    最近在研究如何获取iOS手机性能数据(主要是内存),看了一圈目前主流的方法主要是两种: 1.阿里开源的iOS自动化测试工具tidevice;2.xcode自带的instruments; 1.cpu 正常在20%-40%左右,超过80%需要引起重视。 2.内存 rss:私有内存+所有共享内存,pss:私有内存+比例分配共享内存,

    2024年02月07日
    浏览(34)
  • IOS UDID 6种方法在线获取

    IOS UDID: iOS设备的唯一识别码,每台iOS设备都有一个独一无二的编码,这个编码,就称为识别码,也叫做UDID(Unique Device Identifier) 获取方式: 1、蒲公英 link:蒲公英 | 一步快速获取 iOS 设备的UDID (1)点击蒲公英link (2)ios手机右上角下拉,选择扫一扫,扫描二维码 (3)

    2024年02月07日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包