β οΈ IMPORTANT iOS 16.0+ NOTICE: Apple has deprecatedCTCarrierstarting with iOS 16.0. This means that most carrier-specific information (carrier name, country codes, network codes, etc.) will returnnilor generic values on iOS 16.0 and later versions. This is an Apple platform limitation, not a plugin issue. See the iOS Limitations section for more details.
Carrier Info gets networkType, networkGeneration, mobileCountryCode, mobileCountryCode, e.t.c from both android and ios devices. It's a port from this js project and an improvement on the existing flt_telephony_info package.
Docs: https://developer.android.com/reference/android/telephony/TelephonyManager#getNetworkCountryIso(), https://developer.android.com/reference/android/telephony/SubscriptionManager
 AndroidCarrierData? carrierInfo = await CarrierInfo.getAndroidInfo();
 returns  {
   "isVoiceCapable": true,
   "isDataEnabled": true,
   "subscriptionsInfo": [
     {
       "mobileCountryCode": "310",
       "isOpportunistic": false,
       "mobileNetworkCode": "260",
       "displayName": "T-Mobile",
       "isNetworkRoaming": false,
       "simSlotIndex": 0,
       "phoneNumber": "+15551234567",
       "countryIso": "us",
       "subscriptionType": 0,
       "cardId": 0,
       "isEmbedded": false,
       "carrierId": 1,
       "subscriptionId": 1,
       "simSerialNo": "",
       "dataRoaming": 0
     }
   ],
   "isDataCapable": true,
   "isMultiSimSupported": "MULTISIM_NOT_SUPPORTED_BY_HARDWARE",
   "isSmsCapable": true,
   "telephonyInfo": [
     {
       "networkCountryIso": "us",
       "mobileCountryCode": "310",
       "mobileNetworkCode": "260",
       "displayName": "T-Mobile",
       "simState": "SIM_STATE_READY",
       "isoCountryCode": "us",
       "cellId": {
         "cid": 47108,
         "lac": 8514
       },
       "phoneNumber": "+15551234567",
       "carrierName": "T-Mobile",
       "subscriptionId": 1,
       "networkGeneration": "4G",
       "radioType": "LTE",
       "networkOperatorName": "T-Mobile"
     }
   ]
 }; IosCarrierData? carrierInfo = await CarrierInfo.getIosInfo();
 // iOS 15.x and earlier - Full carrier information available
 returns  {
   "carrierData": [
     {
       "mobileNetworkCode": "20",
       "carrierAllowsVOIP": true,
       "mobileCountryCode": "621",
       "carrierName": "Airtel",
       "isoCountryCode": "ng"
     }
   ],
   "supportsEmbeddedSIM": false,
   "carrierRadioAccessTechnologyTypeList": ["LTE"],
   "isSIMInserted": true,
   "subscriberInfo": {
     "subscriberCount": 1,
     "subscriberIdentifiers": ["subscriber_id_here"],
     "carrierTokens": ["token_here"]
   },
   "cellularPlanInfo": {
     "supportsEmbeddedSIM": false
   },
   "networkStatus": {
     "hasCellularData": true,
     "activeServices": 1,
     "technologies": ["LTE"]
   },
   "_ios_version_info": {
     "ios_version": {...},
     "ctcarrier_deprecated": false,
     "deprecation_notice": "CTCarrier functionality is available on this iOS version."
   }
 }
 // iOS 16.0+ - Limited carrier information due to CTCarrier deprecation
 returns  {
   "carrierData": [
     {
       "mobileNetworkCode": null,
       "carrierAllowsVOIP": null,
       "mobileCountryCode": null,
       "carrierName": null,
       "isoCountryCode": null,
       "_deprecated_notice": "CTCarrier is deprecated in iOS 16.0+. Carrier information is no longer available."
     }
   ],
   "supportsEmbeddedSIM": false,
   "carrierRadioAccessTechnologyTypeList": ["LTE"],
   "isSIMInserted": true,
   "subscriberInfo": {
     "subscriberCount": 1,
     "subscriberIdentifiers": ["subscriber_id_here"],
     "carrierTokens": ["token_here"]
   },
   "cellularPlanInfo": {
     "supportsEmbeddedSIM": true
   },
   "networkStatus": {
     "hasCellularData": true,
     "activeServices": 1,
     "technologies": ["LTE"]
   },
   "_ios_version_info": {
     "ios_version": {...},
     "ctcarrier_deprecated": true,
     "deprecation_notice": "CTCarrier and CTSubscriber are deprecated in iOS 16.0+. Most carrier-specific information is no longer available for privacy and security reasons."
   }
 }- isSIMInserted: Boolean indicating if a SIM card is inserted and active
 - networkStatus: Real-time network connectivity information
 - carrierRadioAccessTechnologyTypeList: Current radio technology (2G, 3G, 4G, 5G)
 
"networkStatus": {
  "hasCellularData": true,        // Cellular data available
  "activeServices": 1,            // Number of active cellular services
  "technologies": ["LTE"]         // Current radio access technologies
}"subscriberInfo": {
  "subscriberCount": 1,                           // Number of subscribers (dual SIM)
  "subscriberIdentifiers": ["subscriber_id"],     // Subscriber identifiers
  "carrierTokens": ["token"]                      // Carrier authentication tokens
}"cellularPlanInfo": {
  "supportsEmbeddedSIM": true     // eSIM support detection
}Use the _ios_version_info field to detect capabilities:
final iosInfo = await CarrierInfo.getIosInfo();
final versionInfo = iosInfo?.toMap()['_ios_version_info'] as Map<String, dynamic>?;
final isDeprecated = versionInfo?['ctcarrier_deprecated'] as bool? ?? false;
if (isDeprecated) {
  // Handle iOS 16.0+ limitations
  print('SIM Inserted: ${iosInfo?.isSIMInserted}');
  print('Network Status: ${iosInfo?.networkStatus?.hasCellularData}');
  print('Radio Tech: ${iosInfo?.carrierRadioAccessTechnologyTypeList}');
} else {
  // Full carrier information available
  print('Carrier: ${iosInfo?.carrierData?.first.carrierName}');
  print('MCC: ${iosInfo?.carrierData?.first.mobileCountryCode}');
}Starting with iOS 16.0, Apple has deprecated the CTCarrier class and related APIs for privacy and security reasons. This affects the following information:
β No longer available on iOS 16.0+:
- Carrier name (
carrierName) - Mobile country code (
mobileCountryCode) - Mobile network code (
mobileNetworkCode) - ISO country code (
isoCountryCode) - VOIP allowance (
carrierAllowsVOIP) 
β Still available on iOS 16.0+:
- SIM insertion detection (
isSIMInserted) - Radio access technology types (
carrierRadioAccessTechnologyTypeList) - Network status (
networkStatus) - Subscriber information (
subscriberInfo) - Cellular plan information (
cellularPlanInfo) 
- 
Check iOS version: Use the
_ios_version_infofield to determine if you're running on iOS 16.0+ and handle the limitations accordingly. - 
Use available features: Focus on features that work across all iOS versions:
// These work on all iOS versions final simInserted = iosInfo?.isSIMInserted ?? false; final hasData = iosInfo?.networkStatus?.hasCellularData ?? false; final radioTech = iosInfo?.carrierRadioAccessTechnologyTypeList ?? [];
 - 
Graceful degradation: Design your app to work without carrier-specific information on newer iOS versions.
 - 
Alternative approaches: Consider using network-based detection or user input for carrier information when needed.
 - 
Android alternative: For apps that require detailed carrier information, consider using the Android implementation which still provides full functionality.
 
The plugin now includes enhanced models for iOS data:
- IosCarrierData: Main container with all carrier information
 - CarrierData: Individual carrier information (nullable fields for iOS 16.0+)
 - SubscriberInfo: Subscriber and carrier token information
 - CellularPlanInfo: Cellular plan provisioning information
 - NetworkStatus: Real-time network connectivity status
 
- Apple Developer Documentation - CTCarrier
 - Apple Developer Documentation - CTSubscriber
 - Apple Developer Documentation - CTCellularPlanProvisioning
 - Stack Overflow Discussion
 - iOS 16.0 Release Notes
 
You should add permissions that are required to your android manifest:
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.READ_BASIC_PHONE_STATE" />
  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />Lots of PR's would be needed to make this plugin standard, as for iOS there's a permanent limitation for getting the exact data usage, there's only one way around it and it's super complex.