📱

iOS 5G対応ことはじめ

9 min read

初めに

各ケータイキャリアが5Gを盛り上げようとがんばっていますが、iPhoneにおいては、昨年発売されたiPhone 12シリーズから5Gに対応しています。

日本国内において5Gを利用できる場所はまだ限られていますが、幸いにも自分の日常的な活動範囲で5Gの利用ができることに気づきました。[1]
そこで、調査も兼ねて少しだけ触れてみたので、備忘録も兼ねて記事にしておきます。

5Gの特徴

まず前提知識として5Gによって何が変わるのかざっくりおさらい。
不要な方は次のセクションまで読み飛ばしてください。

  1. 高速・大容量
  2. 低遅延
  3. 多接続

理論値では、4Gに比べて最大で「通信速度は20倍、遅延は10分の1、同時接続数は10倍」になるとのこと。

https://iot.kddi.com/5g/

高速・大容量

高速かつ大容量な通信が可能になることで、まずシンプルにリッチなコンテンツをモバイル回線でも楽しめるようになります。

  • マルチストリーム4K再生
    • マルチアングルも
  • 今まで速度や容量の問題で事前にダウンロードしてオフライン動作させていたものでも、オンラインでリアルタイムに

ex. Red Bull Media House

https://youtu.be/sIaYghItvp0?t=61

低遅延

遅延がなくなれば、遠隔でのリアルタイムなやり取りがよりスムーズに。

  • リアルタイムコラボレーション
    • オンラインゲーム
    • 遠隔AR作業

多接続

局所的に混雑した場所でTwitterすらままならない、という経験をしたことがある人は多いことでしょう。5Gではより多くの接続ができることから、快適なモバイルインターネット環境を手に入れることができるかもしれません。
また、それ以外にもIoT機器を今よりも多く利用することで、便利になるケースもあるかもしれません。

  • ライブ会場などたくさん人が集まるような環境でも快適に通信
  • より多くのセンサー機器を設置して精度向上

5Gの種類

自分も詳しくないのでざっくりとした説明に留めますが、5Gは2種類存在することを覚えておくと良いでしょう。

  • 4G設備を活用したノンスタンドアローンモード(5G NSA)
  • 5Gのために設計された設備のみを使ったスタンドアローンモード(5G SA)


https://www.softbank.jp/corp/news/press/sbkk/2021/20211019_01/

実装のポイント

ここから本題になります。

NG

Wi-Fi含め、どのネットワークが高品質か判断する必要があるので、ネットワークインターフェースタイプで判断してはいけません。
接続状況によって、5Gよりも4G、Wi-Fiよりも5Gが高品質なケースはあります。

理論値

  • 5G 10Gbps-20GBbps[2]
  • Wi-Fi 6 9.6GBbps[3]

一応4Gと5Gを区別できるAPIは存在しています。
5Gの場合スタンドアローンかどうかまでわかるようです。

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 NSA(ノンスタンドアローン)")
        case CTRadioAccessTechnologyNR:
            print("5G SA(スタンドアローン)")
        default:
            print("LTE,5G以外")
        }
    }
}

OK

Appleによると、基本的にはハイレベルなAPIを使うことを推奨しています。[^44]
例えば URLSessionAVURLAssetNWConnection などがそれに当たるようです。

重要になってくるのは constrainedexpensive という2つの概念です。
これらは5Gのために新設されたものではなく、iOS 13の時代から存在しています。

constrained

iPhoneのモバイル通信設定が省データモードになっていると、constrained という状態で表されるようです。

https://developer.apple.com/documentation/foundation/urlerror/networkunavailablereason/constrained

constrained な状況下では、極力通信はしないように心がけるべきなので、必須ではないアセットダウンロードを控えるなど、通信を減らす努力が求められます。

expensive

こちらはOSが様々な状態を複合的に判断しているようで、一概に言い表すことができないのですが、簡単に言ってしまうと、好き放題大量に通信できる状態ではないという状態になります。

例えば4G回線は基本的には expensive と判断されるようです。
5G回線であったとしても、expensive と判断されることはあり、端末の状態や設定に依存します。[4]
また、Wi-Fi環境下でも通信状態によっては expensive と判断されることもあるようです。

https://developer.apple.com/documentation/foundation/urlerror/networkunavailablereason/expensive

expensive な状況下では、省データモードほどではないけれど、潤沢に通信できるわけではないので、例えば低画質なアセットをダウンロードするなど、通信量を減らす努力が求められています。

まとめ

つまり、通信のハンドリング方法という意味では、5Gであるかどうかは意識せず、constrainedでもexpensiveでもない時(制限を受けていない時)は全力でフェッチして良いと判断するのが、良い実装ということになります。

一方で UIまで視野を広げてみると、今までモバイル環境では(おそらくほぼ100%) expensive だったので、その前提でUIが表現されているケースもあることでしょう。
今後5Gの普及によってモバイル回線でも expensive になるとは限らないということは、UI上も気をつけたいポイントです。

API例

URLSession

URLSessionConfiguration または URLRequest で設定します。

let config = URLSessionConfiguration.default
config.allowsExpensiveNetworkAccess = false
config.allowsConstrainedNetworkAccess = false

let session = URLSession(configuration: config)
var request = URLRequest(url: URL(string: "https://example.com")!)
request.allowsExpensiveNetworkAccess = false
request.allowsConstrainedNetworkAccess = false

URLSession.shared.dataTask(with: request)

allowsConstrainedNetworkAccess

false にすると省データモードで通信ができません。

In iOS 13 and later, users can set their device to use Low Data Mode as one of the Cellular Data Options in the Settings app. Users can turn on Low Data Mode to reduce your app’s network data usage. This property controls a URL session’s behavior when the user turns on Low Data Mode.

Limit your app’s of use of constrained network access to user-initiated tasks, and put off discretionary tasks until a nonconstrained interface becomes available.

https://developer.apple.com/documentation/foundation/urlsessionconfiguration/3235751-allowsconstrainednetworkaccess

allowsExpensiveNetworkAccess

false にするとOSがネットワーク状態を良好と判断しない限り通信ができません。

The system determines what constitutes “expensive” based on the nature of the network interface and other factors. iOS 13 considers most cellular networks and personal hotspots expensive.

Limit your app’s of use of expensive network access to user-initiated tasks, and put off discretionary tasks until a nonexpensive interface becomes available.

https://developer.apple.com/documentation/foundation/urlrequest/3358305-allowsexpensivenetworkaccess

isDiscretionary

true にすると端末の状態によってバックグラウンドでの通信を遅らせます。
こちらも併用すると良さそう。

When transferring large amounts of data, you are encouraged to set the value of this property to true. Doing so lets the system schedule those transfers at times that are more optimal for the device. For example, the system might delay transferring large files until the device is plugged in and connected to the network via Wi-Fi. The default value of this property is false.

The session object applies the value of this property only to transfers that your app starts while it is in the foreground. For transfers started while your app is in the background, the system always starts transfers at its discretion—in other words, the system assumes this property is true and ignores any value you specified.

https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1411552-isdiscretionary

waitsForConnectivity

true にすると、通信失敗してもすぐにエラーを返さず、ネットワーク状態がよくなったらリトライしてくれます。
例えば allowsExpensiveNetworkAccessfalse に設定しつつ、こちらを true にすることで、快適な5GやWi-Fiに接続するまで通信させずに待機させることができます。

If the value of this property is true and sufficient connectivity is unavailable, the session calls the URLSession:taskIsWaitingForConnectivity: method of NSURLSessionTaskDelegate and waits for connectivity. When connectivity becomes available, the task begins its work and ultimately calls the delegate or completion handler as usual.

https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/2908812-waitsforconnectivity

AVURLAsset

URLSession の設定とほぼ同じ。

https://developer.apple.com/documentation/avfoundation/avurlasset/initialization_options
  • AVURLAssetAllowsConstrainedNetworkAccessKey
  • AVURLAssetAllowsExpensiveNetworkAccessKey

NWConnection

URLSession などとは反対になっており、禁止する方を true にします。

  • prohibitedInterfaceTypes

https://developer.apple.com/documentation/network/nwparameters/2998703-prohibitedinterfacetypes
  • requiredInterfaceType

https://developer.apple.com/documentation/network/nwparameters/2998706-requiredinterfacetype

実験してみた

URLSession を用いて少し実験してみてわかったことの備忘録。

  • allowsConstrainedNetworkAccess のみ false にして通信した場合
    • 自宅のWi-Fi接続中は通信エラーにならないことを確認
    • モバイル回線利用中は省データモードの場合のみconstrained と判定され通信エラー
  • allowsExpensiveNetworkAccessallowsConstrainedNetworkAccess のどちらも false にして通信した場合
    • 自宅のWi-Fi接続中は通信エラーにならないことを確認
    • 4G/5G共に省データモードにしても constrained とは判定されずに expensive と判定され通信エラー
    • 5G(au povo 1.0)では、標準省データモードの場合 expensive になり、5Gでより多くのデータを許容にすると通信できた
5Gでより多くのデータを許容 標準/省データモード 省データモード

備考 - iPhoneの5G関連の設定方法

設定 > モバイル通信 > 通信のオプション > データモード

キャリアのプランによってはここがデフォルトで「5Gでより多くのデータを許容」になっているとかいないとか。

5Gでより多くのデータを許容 標準

https://support.apple.com/ja-jp/HT211828
脚注
  1. auユーザーなんですが、幸いにもsub6エリアで活動していたりします。ただまぁだいたいは裏側4G LTEな5Gに繋がることの方が多いです https://www.au.com/mobile/area/5g/#anc_03 ↩︎

  2. とはいえ現状日本国内ではドコモの4.2Gbpsが最大 https://www.nttdocomo.co.jp/area/5g/ ↩︎

  3. バッファローのWi-Fi 6についてのざっくりした解説 https://www.buffalo.jp/contents/topics/knowledge/wi-fi6/ ↩︎

  4. キャリアのプランも考慮しており、使い放題プランならexpensiveではないと判断される、というような噂も耳にしましたが、真偽は不明です。そんな高級プラン契約してないので試せない😇 ↩︎

Discussion

ログインするとコメントできます