プロファイルを使用せずにWifiホットスポットの構成をアプリに組み込む方法

##何をするのか？
Wifiプロファイルを使用せずに、Wi-Fiスポットの自動設定をアプリから行います。このプロファイルとは、Wifiを使用するための証明書であり、内部にはSSIDやパスワード、説明などそのWifiに接続するための情報が記載されているものです。本来はこのプロファイルを端末にインポートして、SSIDやPASSの自動設定がWifi選択時にされるため、タップするだけでWifiに接続できます（AuやDocomoなどのWifiを使用する際に、その会社の端末だけ接続出来たりするのがこれにあたる。これは、もともと端末にプロファイルがインポートしているため可能になる）。しかし今回はプロファイルインポートなどの手間をなくすために、**NEHotspotConfiguration・NEHotspotConfigurationManager**というswitのクラスを使用して、アプリの中にWifiホットスポットへの接続機能の組み込みを行います。

##NEHotspotConfiguration<br>NEHotspotConfigurationManagerとは？
iOS11からNEHotspotConfiguration、NEHotspotConfigurationManagerというクラスが追加され、Wi-Fiスポットのアプリからの設定を可能にしました。また、設定したホットスポット構成は、アプリが起動している間だけ有効にしたり、有効期限を設定することも可能にします。

##今回使う機能
###フレームワーク
**NENetworkExtension.framework**
上記であげたクラスを使用するためにこのフレームワークをインポートする必要があります。

```swift
//フレームワークをインポート
import NetworkExtension
```
###クラス
|名前|機能|
|:----------|:-----------|
|NEHotspotConfigurationManager|登録したWi-Fiスポットとの接続・除去の管理|
|NEHotspotConfiguration|接続したいWi-Fiスポットの設定を格納|

###メソッド(NEHotspotConfigurationManager)
|名前|機能|
|:----------|:---------|
|apply()|接続を促すダイアログを出現|
|removeConfiguration()|※今回は使用しません<br>直近で接続したWi-Fiスポットの情報を消去|

###プロパティ(NEHotspotConfigurationManager)
|名前|機能|
|:--|:--|
|NEHotspotConfigurationManager.shared|シングルトンのインスタンスを取得|

###プロパティ(NEHotspotConfiguration)
|名前|機能|
|:----------------|:--|
|joinOnce|接続に関する制限ができる。また、Trueにすると、フォアグラウンド状態の時しか接続しないなどの制限ができる|
|lifeTimeInDays|設定を何日保持するか(1~365日で設定)|

##実装コード

```swift
//インスタンスの生成
let manager = NEHotspotConfigurationManager.shared()
//仮のSSIDを代入
let ssid = "MyHotspot"
//仮のPASSWORDを代入
let password = "**********"
//後ほど利用するisWEPの値としてtureを代入
let isWEP = true
//変数にWifiスポットの設定を代入
var hotspotConfiguration = NEHotspotConfiguration(ssid: ssid, passphrase: password, isWEP: isWEP)
//上記で記述したWifi設定に対して制限をかける。
hotspotConfiguration.joinOnce = true
//ここでも有効期限として制限をかける。
hotspotConfiguration.lifeTimeInDays = 1

//ダイアログを出現させる。
manager.apply(hotspotConfiguration) { (error) in
  if let error = error {
     print(error)
  } else {
     print("success")
  }
}
```
まず最初にシングルトンのインスタンスを生成する。この**シングルトン（Signleton)**とは一種のデザインパターンであり、そのクラスのインスタンスが絶対に一つだけであることを保証してくれるものです。

```swift
let manager = NEHotspotConfigurationManager.shared()
```
次にssidとpasswordを定数として宣言します。ここで宣言されているのは仮の値ですが、本来こういったアプリケーションを実装する場合はAPIを利用して、接続したWifiのSSIDとPasswordを取ってくるのが主流です。

```swift
//仮のSSIDを代入
let ssid = "MyHotspot"
//仮のPASSWORDを代入
let password = "**********"
```
次は定数isWEPにtrueを代入します。これは後ほどWifiスポットの設定をする際に用います。今の時点ではisWEPの値はtrue or falseのBool値が入ることを頭に入れておいてください。

```swift
//後ほど利用するisWEPの値としてtureを代入
let isWEP = true
```
次に変数にNEHotspotConfigurationで設定したWifiスポットの情報を格納します。ssid:の欄にssidの値を記述し、psssphrase:の欄にpasswordの値を記述します。そしてisWEPにはtrueかfalseのBool値を設定します。このisWEPというのは、パスワードの形式を表しています。tureならばWEPという形式の場合、64-bitWEPという10桁のパスか、128bitWEPという26桁の16進数を選択したことになります。falseならばWPA/WPA2という8~63文字のキャラクタで出来たパスを指定したことになります。

```swift
var hotspotConfiguration = NEHotspotConfiguration(ssid: ssid, passphrase: password, isWEP: isWEP)
```
次に上記で宣言したhotspotConfiguration変数にjoinOnceプロパティで制限をかけていきます。ここではtrueを宣言していますので、フォアグランド状態（今画面に写っている画面）の時しかWifi接続が出来にないように設定します。

```swift
hotspotConfiguration.joinOnce = true
```

次はlifeTimeInDaysプロパティによって、Wifiの接続日数を決めます。ここでは１日を指定しているので、１日経ったら再度接続し直さないと繋がらないように設定しています。

```swift
hotspotConfiguration.lifeTimeInDays = 1
```
次にmanagerにapplyメソッドを用いて接続を実行します。引数に先ほどWifi設定が格納された変数を格納することで、指定のWifiに接続できます。そしてmanagerには登録したWifiスポットの接続・除去を管理するNEHotspotConfigurationManagerが格納されているので、これでWifiの管理ができるようになりました。そして、最後に接続と同時にSuccessかerrorのダイアログを画面に出力して終了です。

##最後に
自分の学習整理用の記事でもあるので、わかりにくい点あると思いますが参考になったら幸いです。
ここで整理仕切れなかったことなどはまた次回の投稿で説明できたらと思うので、もし気が向いたら次回以降もご覧ください。

**次の記事**
プロファイルを使用せずにWifiホットスポットの構成をアプリに組み込む方法2（切わけ編）
https://qiita.com/Howasuto/items/ebb2e2ce0497faa228b5
##参考
https://dev.classmethod.jp/smartphone/nehotspotconfiguration/
https://houwa-js.co.jp/blog/2018/12/20181204/
https://developer.apple.com/documentation/networkextension/nehotspotconfiguration/2866705-init