1 import CoreTelephony 2 import ABI47_0_0ExpoModulesCore 3 4 public class CellularModule: Module { definitionnull5 public func definition() -> ModuleDefinition { 6 Name("ExpoCellular") 7 8 Constants { 9 Self.getCurrentCellularInfo() 10 } 11 12 AsyncFunction("getCellularGenerationAsync") { () -> Int in 13 Self.currentCellularGeneration().rawValue 14 } 15 16 AsyncFunction("allowsVoipAsync") { () -> Bool? in 17 Self.currentCarrier()?.allowsVOIP 18 } 19 20 AsyncFunction("getIsoCountryCodeAsync") { () -> String? in 21 Self.currentCarrier()?.isoCountryCode 22 } 23 24 AsyncFunction("getCarrierNameAsync") { () -> String? in 25 Self.currentCarrier()?.carrierName 26 } 27 28 AsyncFunction("getMobileCountryCodeAsync") { () -> String? in 29 Self.currentCarrier()?.mobileCountryCode 30 } 31 32 AsyncFunction("getMobileNetworkCodeAsync") { () -> String? in 33 Self.currentCarrier()?.mobileNetworkCode 34 } 35 } 36 37 // MARK: - internals 38 39 // Keep this enum in sync with JavaScript 40 // Based on the EffectiveConnectionType enum described in the W3C Network Information API spec 41 // (https://wicg.github.io/netinfo/). 42 enum CellularGeneration: Int { 43 case unknown = 0 44 case cellular2G = 1 45 case cellular3G = 2 46 case cellular4G = 3 47 case cellular5G = 4 48 } 49 currentCellularGenerationnull50 static func currentCellularGeneration() -> CellularGeneration { 51 let radioAccessTechnology = currentRadioAccessTechnology() 52 53 switch radioAccessTechnology { 54 case CTRadioAccessTechnologyGPRS, 55 CTRadioAccessTechnologyEdge, 56 CTRadioAccessTechnologyCDMA1x: 57 return .cellular2G 58 case CTRadioAccessTechnologyWCDMA, 59 CTRadioAccessTechnologyHSDPA, 60 CTRadioAccessTechnologyHSUPA, 61 CTRadioAccessTechnologyCDMAEVDORev0, 62 CTRadioAccessTechnologyCDMAEVDORevA, 63 CTRadioAccessTechnologyCDMAEVDORevB, 64 CTRadioAccessTechnologyeHRPD: 65 return .cellular3G 66 case CTRadioAccessTechnologyLTE: 67 return .cellular4G 68 default: 69 if #available(iOS 14.1, *) { 70 if radioAccessTechnology == CTRadioAccessTechnologyNRNSA || 71 radioAccessTechnology == CTRadioAccessTechnologyNR { 72 return .cellular5G 73 } 74 } 75 return .unknown 76 } 77 } 78 getCurrentCellularInfonull79 static func getCurrentCellularInfo() -> [String: Any?] { 80 let carrier = Self.currentCarrier() 81 let generation = Self.currentCellularGeneration() 82 83 return [ 84 "allowsVoip": carrier?.allowsVOIP, 85 "carrier": carrier?.carrierName, 86 "isoCountryCode": carrier?.isoCountryCode, 87 "mobileCountryCode": carrier?.mobileCountryCode, 88 "mobileNetworkCode": carrier?.mobileNetworkCode, 89 "generation": generation.rawValue 90 ] 91 } 92 currentRadioAccessTechnologynull93 static func currentRadioAccessTechnology() -> String? { 94 let netinfo = CTTelephonyNetworkInfo() 95 96 if #available(iOS 12.0, *) { 97 return netinfo.serviceCurrentRadioAccessTechnology?.values.first 98 } else { 99 return netinfo.currentRadioAccessTechnology 100 } 101 } 102 currentCarriernull103 static func currentCarrier() -> CTCarrier? { 104 let netinfo = CTTelephonyNetworkInfo() 105 106 if #available(iOS 12.0, *), let providers = netinfo.serviceSubscriberCellularProviders { 107 for carrier in providers.values where carrier.carrierName != nil { 108 return carrier 109 } 110 return providers.values.first 111 } 112 return netinfo.subscriberCellularProvider 113 } 114 } 115