3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

iOSで5Gかどうか判断する(罠付き)

Posted at

前提

Xcode Version 12.4 (12D4e)で動作確認しています。

概要

iOSでCoreTelephonyを使って、今使っているキャリアが5Gかどうかを判別します。
また、その際の罠について紹介します。

結論

iOS 14.1以上で、5Gかどうかの判断をするようにしましょう。

今使っているキャリアを取得

まず、CTTelephonyNetworkInfoを生成します。
CTTelephonyNetworkInfoからserviceSubscriberCellularProviders を使って端末のキャリアを取得します。
keyとともに CTCarrier を取得できます。

        let info = CTTelephonyNetworkInfo()
        info.serviceSubscriberCellularProviders?.forEach({ (key, value) in
            print(value.carrierName ?? "")
        })

無線テクノロジーを取得

先ほど得たキーで、serviceCurrentRadioAccessTechnologyより無線のテクノロジーが何であるかを取得可能です。
CoreTelephonyのドキュメントに Radio Access Technology Constantsがあるので、switchを使って目的の無線テクノロジーを検出できます。

CTRadioAccessTechnologyNR,CTRadioAccessTechnologyNRNSAは5Gになります。
二つの違いはスタンドアローン型か非スタンドアローン型かの違いです。詳しくはWikipediaを貼っておきます。
https://ja.wikipedia.org/wiki/5G_NR#展開方式

        let info = CTTelephonyNetworkInfo()
        info.serviceSubscriberCellularProviders?.forEach({ (key, value) in
            if let radioAccessTechnology = info.serviceCurrentRadioAccessTechnology?[key] {
                switch radioAccessTechnology {
                case CTRadioAccessTechnologyLTE:
                    print("これはLTEです")
                case CTRadioAccessTechnologyNRNSA:
                    print("これは非スタンドアローンモード 5Gです")
                case CTRadioAccessTechnologyNR:
                    print("スタンドアローンモード 5Gです")
                default:
                    print(radioAccessTechnology)
                }
            }
        })

iOS 13以下への対応

しかしながら、開発中のアプリがiOS13以降にも対応するとなると、このコードだとエラーが起きます。

スクリーンショット 2021-03-25 15.10.00.png

'CTRadioAccessTechnologyNRNSA' is only available in iOS 14.0 or newer
ということなので、version checkのコードを追加します。

        let info = CTTelephonyNetworkInfo()
        info.serviceSubscriberCellularProviders?.forEach({ (key, value) in
            if let radioAccessTechnology = info.serviceCurrentRadioAccessTechnology?[key] {
                switch radioAccessTechnology {
                case CTRadioAccessTechnologyLTE:
                    print("これはLTEです")
                default:
                    if #available(iOS 14.0, *) {
                        switch radioAccessTechnology {
                        case CTRadioAccessTechnologyNRNSA:
                            print("これは非スタンドアローンモード 5Gです")
                        case CTRadioAccessTechnologyNR:
                            print("スタンドアローンモード 5Gです")
                        default:
                            print(radioAccessTechnology)
                        }
                    } else {
                        print(radioAccessTechnology)
                    }
                }
            }
        })

ここから罠

実はこのコード、iOS 14.0系のOSで実行するとクラッシュします
理由はCTRadioAccessTechnologyNRNSAとCTRadioAccessTechnologyNRの部分で、
実はこの二つの定数はiOS 14.1からのAPIであるとの記載がWebのドキュメントにあります。

しかしながら、Xcodeで定義にジャンプするとこれらのAPIは @available(iOS 14.0, *) でマークされています。
このため、対応OSと定義で不整合が起きて、iOS 14.0に本来無いAPIに触ろうとしてクラッシュするわけです。

対策

#available の部分を iOS 14.1に変更しましょう。
これで本来APIが使えるOSだけがAPIに触ることになります。

        let info = CTTelephonyNetworkInfo()
        info.serviceSubscriberCellularProviders?.forEach({ (key, value) in
            if let radioAccessTechnology = info.serviceCurrentRadioAccessTechnology?[key] {
                switch radioAccessTechnology {
                case CTRadioAccessTechnologyLTE:
                    print("これはLTEです")
                default:
                    if #available(iOS 14.1, *) {
                        switch radioAccessTechnology {
                        case CTRadioAccessTechnologyNRNSA:
                            print("これは非スタンドアローンモード 5Gです")
                        case CTRadioAccessTechnologyNR:
                            print("スタンドアローンモード 5Gです")
                        default:
                            print(radioAccessTechnology)
                        }
                    } else {
                        print(radioAccessTechnology)
                    }
                }
            }
        })

ちなみに

Xcode Version 12.5 beta 3 (12E5244e)だと、この問題は解決されていて、CTRadioAccessTechnologyNRNSAとCTRadioAccessTechnologyNRは @available(iOS 14.1, *) でマークされています。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?