All right, so I have an app that requires reading the data from the SIM card. More precisely I need the Carrier name, MCC, MNC, ISO Country code and current Radio Access Technology (Okay this does not directly come from the SIM card but it is linked). It works perfectly on every phone, but I realized (after testing) that I'm in trouble with the newest iPhones that have an eSIM set up. I have no idea how to tell my app to read the data of the physical SIM card instead of the eSIM.
I tried to search a bit on the Web about that but I found absolutely nothing...
The code I use:
let telephonyInfo: CTTelephonyNetworkInfo = CTTelephonyNetworkInfo()
carrierNetwork = telephonyInfo.serviceCurrentRadioAccessTechnology?.first?.value ?? "null"
carrierNetwork = carrierNetwork.replacingOccurrences(of: "CTRadioAccessTechnology", with: "", options: NSString.CompareOptions.literal, range: nil)
let carrier = telephonyInfo.serviceSubscriberCellularProviders?.first?.value // actually here originally I tried to use ?.values.first, but the result is the same
let countryCode = carrier?.mobileCountryCode ?? "null"
let mobileNetworkName = carrier?.mobileNetworkCode ?? "null"
let carrierName = carrier?.carrierName ?? "null"
let isoCountrycode = carrier?.isoCountryCode?.uppercased() ?? "null"
/* so the problem is that the values I get are the ones from the eSIM when it is set up. If it is not, then I get the values I want. Apparently, when the physical SIM card line is set as primary, it works. But I need that code to systematically use the physical SIM data. */
Example:
I expect [physical SIM card]: Carrier name: Free, MCC: 208, MNC: 15, ISO Country Code: fr, CTRadioAccessTechnology: WCDMA.
But instead, I get [eSIM]: Carrier name: Swisscom, MCC: 228, MNC: 01, ISO Country Code: ch, CTRadioAccessTechnology: LTE.
EDIT: If you know how I can read both, that's also fine to me, my goal is to detect if the user uses a Free Mobile [208 15] SIM card.
Thank you in advance,
Your code is always getting the first entry from
serviceSubscriberCellularProviders
and
serviceCurrentRadioAccessTechnology
dictionaries, but dictionaries don’t have a defined order. Thus, you’ve no idea which info you’re getting; there’s not even any guarantee that you’ll get the same info between different executions of your app.
If you know how I can read both, that's also fine
For that you can enumerate the
serviceSubscriberCellularProviders
dictionary and then the ‘key’ value to access the
serviceCurrentRadioAccessTechnology
dictionary. For example:
let info = CTTelephonyNetworkInfo()
for (service, carrier) in info.serviceSubscriberCellularProviders ?? [:] {
let radio = info.serviceCurrentRadioAccessTechnology?[service] ?? ""
… `radio` is now a value that matches `carrier` …
}
There’s still no guarantee about the order though. However, it seems like you plan to search through this list for the value you want, and that’s quite feasible.
Also, with regards this:
carrierNetwork.replacingOccurrences(of: "CTRadioAccessTechnology", with: "", options: NSString.CompareOptions.literal, range: nil)
I’m not sure what you’re trying to do here but this code is not valid. The values returned by
currentRadioAccessTechnology
and
serviceCurrentRadioAccessTechnology
are only intended to be compared to the various
CTRadioAccessTechnologyXXX
constants; you can’t parse the string and expect to get back meaningful results.
If you want to show the radio technology to the user, you’ll need your own mapping from these constants to an appropriate display name.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"