ビギグラマーのノート

自作PCやプログラミングについてのブログです。

SIMフリーiPhoneの罠

 前置き

 最近の格安SIMの広がりを見ると凄まじいものがあり、多くの人が格安SIMないしはSIMフリースマートフォンに興味を持っているかと思います。日本の携帯事情といえば、Androidのシェアが増えてきたものの以前iOSiPhoneとか)の人気は高いままです。このiPhoneに携帯電話会社の回線の縛りなく格安SIMを入れる場合SIMフリーiPhoneが必要となります。(最近はSIMロックがかかっていてもそのまま使える格安SIMも増えてきました)  しかしSIMフリーiPhoneには思わぬ注意点があるのです。

入手

 さて少し話が逸れますが、まずSIMフリーiPhoneをどのようにして入手するのかを説明していきたいと思います。SIMフリーiPhoneは携帯電話会社のショップには売っていません。主にインターネットか、Apple Storeでの購入となります。

www.apple.com

 もしくはSIMロックのかかっていない海外の携帯会社版のiPhoneを買うこととなります。例えばアメリカのVerizonは4G携帯全てにSIMロックをかけないというポリシーになっているため、アメリカの他の携帯電話会社や日本の携帯電話会社などのSIMを使用することが可能です。このよなものを日本で使用する場合バンド(周波数)をよく確認する必要があります。次の見出しではバンドに関する注意点を米Verizon版iPhone7を例にして書きます。

日本で使える周波数

 まず海外でSIMフリーiPhoneを購入する際の注意点はこちらです。当たり前ですが、日本のApple Store等で買ったSIMフリーiPhoneはこの周波数の問題をクリアしています。

日本版の周波数

f:id:BegiGrammer:20161003125612p:plain

 日本の通信方式のほとんどをカバーする北米版iPhone7を買う際はA1660, A1661となります。米国でCDMAを利用しているのはVerizon, Sprintの二社なのでそちらのiPhoneを買うことになります。ただしSprintは過去に米国内の他のキャリアをロックしたiPhoneを発売したことがあるのでVerizonの方が確実と言えるでしょう。

 もし、A1778, A1784を手にいれて日本で使った場合まずauでは3G回線が使えません。なぜならauはCDMA2000というマイナー方式をとっているからです。(またアクティベートができないようです) docomoではまず800MHz帯の使用ができません。ここはプラチナバンドと呼ばれ、混み合った場所でも通信環境が保証されやすい帯域です。そのため1700MHz帯とバンド1での3G通信となります。(一般的に数字が小さいほど低速ですが、ビルの中や山の上などの劣悪な環境でも繋がりやすいと言われます)Softbankでは日本版と変わらず900MHzから3G使用できます。

 一方でLTEは大体どこも対応しています。

 これらのキャリアは基本的にSIM単体での販売をしていないのでUnlocked iPhone格安SIMで使用することになります。

 例えばyモバイルは3Gに1700MHz, LTEにBand3, 28を使用しているのでA1778等でも問題なく使用できるはずです。

 このようにSIMを売っている携帯電話会社のバンドと対応しているバンドとをよく見て一番適当なものを買うということをオススメします。

アクティベート

 さてSIMフリーiPhoneを買ったからといってすぐさまSIMを挿入しないでください。そもそもSIMフリーiPhoneSIMロックiPhoneの中身は同じであり、アクティベーションサーバーと呼ばれるサーバーでiPhoneの登録(Appleアカウントなどでなくもっと技術的な意味)の際にSIMフリーの証がつけられているかどうかでしかありません。すなわち、アクティベーションサーバーにうまく認識されなければSIMフリーが外れロックがかかることもあり得ます。

 そのようなことがあり得るのでしょうか?

 私は一度経験したことがあります。Verizon版携帯をアメリカで購入し、T-mobileで使用していたSIMフリーiPhoneが、帰国しDocomoのSIMを挿入した際にSIMロックで弾かれたことがありました。すなわち私のそのSIMフリーiPhoneT-mobileSIMロックされていたのです。

 これは特段珍しい話ではなく、インターネットで検索すると幾らかの事例が出てきます。

 「アクティベーションサーバーにうまく認識されない」とはアクティベーションサーバーがメンテナンス中にSIMを挿入し初期起動しアクティベートしたiPhoneはそのSIMでロックがかかるという現象のことです。

 それでは、どのようにしてサーバーの誤認識を防げば良いのでしょうか?アクティベーションサーバーのメンテナンスはアメリカ時間の休日に行われることが多く、平日にSIMの挿入と初期起動(アクティベート)を行うことである程度は防ぐことができます。また、一度SIMを挿入したiPhoneの設定やコンテンツを全て削除しもう一度アクティベーションを行うということはこのようなリスクを伴うのでなるべく控えた方がよいと思います。

(この情報は日本Apple Storeの店員さんから聞いた情報です)

 

SIMロックがかかったら?

 SIMフリーiPhoneにロックがかかった場合どのようにしたら良いのでしょうか?まずApple Japanに連絡しアクティベーションサーバーでの登録の具合を確認してもらいましょう。そして再度SIMフリーにしてもらいます。これが確実にできるのは日本で買ったSIMフリーiPhoneであり、海外版は基本的にその国のAppleの仕事となるので日本のApple Storeではできない可能性があります。

Apple Careの問題

f:id:BegiGrammer:20170520155355j:plain

 これはSIMフリーに限った話ではなく、海外版iPhone全体の問題となります。Apple Careでは画面割れだったら画面の交換修理を、本体にもダメージが及んでいる問題の場合本体の交換を行います。この本体の交換の際に交換できるのは同じ周波数モデルのiPhone同士だけです。iPhone7を例に出すと北米版A1660を交換する場合、日本には同じモデルのがないため同モデルをアメリカから取り寄せとなります。

 また交換品が何かの手違いでSIMロックがかかっているものが送られることがありました。その場合サーバー上でSIMロックを解除する必要がありますが、アメリカ版などの海外版はその申請が何かと面倒で、その海外のがなかなかロック解除に応じてくれない場合あるそうです。

まとめ

 SIMフリーiPhoneを購入する際はなるべく国内版のSIMフリーiPhoneApple Storeで購入することをお勧めします。その場合、SIMを刺す時の日時を少し念頭に置いてアクティベートするとより安全に使用できます。

【Swift】PageBased ApplicationにPage Controlを表示する

導入

 Xcodeにはいくつかの雛形が用意されておりその中にPage-based Applicationがあります。Page-based ApplicationはiOSのホーム画面のように横スクロールでいくつかのページを表示する場合や、Bookアプリのようにめくってページ移動をする場合に使われています。その時に役立つのがPage Controlと呼ばれる「・・・」みたいなドットです。

f:id:BegiGrammer:20170517220206p:plain

 雛形のアイコンにはあたかもPage-based Applicationの代名詞とでもいうかのようにPage Controlのイメージが書いてあるのですが、実際の雛形の中にこれは含まれません。そこで今回はこいつを作ります。

下準備

 作られたばかりのPage-based Applicationは(いかにもデザインセンスの無い色の)めくりカレンダーのようなものになっています。今回はPage Controlの追加なのでこれを横スクロールのiOSのメイン画面のようにします。

 RootViewController.swift、20行目のtransitionStyle.pageCrulから.scrollに変更します。これだけで横スクロールになります。ちなみにその横のnavigationOriantation.horizontalから.verticalに変更すると上下スクロールになります。

f:id:BegiGrammer:20170517225748p:plain

 PageControl追加

 ようやくPage Controlを追加します。現在はRootViewControllerの上にDataViewControllerをaddSubview()している状態なので、またその上にPage Controlを表示します。すなわちRootViewController.swiftでDataViewControllerをaddSubview()した後に新たにPage ControlをaddSubview()します。

 全部載せるほどのものでも無いので変更部分のみ書いてあります。もちろん、pageControlはクラス変数として作っておいてください。

 pageControlを追加するのはRootViewController.swiftの大体30行目、DataViewControllerを追加した後にしてください。Page ControlのデフォルトのpageIndicatorTinColorcurrentPageIndicatorTinColorは透明になっているので、適当な色を指定してください。今回はlightGraydarkGrayを使用しています。func pageViewController()はページをめくる際に呼び出されます。その中で使っているindexOfViewController()ModelControllerクラスの中で定義しています。これに目前(pending)のViewControllerを入れています。同じ関数でページめくりのアニメーションが終わった際に呼び出されるもの(2つめ)の中ではindexの取得がうまくいきません。ページめくりのフェイントに対応するためPageControlの更新はアニメーションが終了した時点で行います。pageControl.currentPageはデフォルトが0で(今回は明示的に0を代入しています)これに現在のindexを代入することで、darkGrayなドットが移動します。

タップでページ移動

 あまり使用している人はいないと思いますが、実はPageControlのドットの右側や左側をタップするとページが進んだり戻ったりします。あまり使われない機能をいちいち書くのが面倒なので、かけたら書きます。そのうち・・・

【Swift3】WKwebViewでWebページのアイコンを自動取得

 作成意図

 Webページにはappleバイス用のアイコンが設定されている場合があり、これが主にブックマークを使用する際のアイコン画像となります。現在このアイコンを取得する機能はWKWebViewに実装されておらず、自力で導入する必要があります。しかし、毎回これを書いていては骨が折れるので、アイコンを取得できるカスタムWKWebViewを作成しました。

ダウンロード

Get url where web page icon. · GitHub

 使い方

 CustomWKWebView.swiftとscript.jsをアプリケーションのディレクトリに置き、xcodeに登録してください。

 CustomWKWebViewDelegateをスーパクラスにしてください。

 webView.getIconImage() を実行すると現在表示中のページのアイコンの取得を試みます。 func urlDidGet(customWebView: , arrURL:) がアイコンの取得時に呼び出されます。以下がサンプルの使い方になります。

 ライセンス

 このカスタムは営利非営利のどちらでも使用可能です。ただし二次配布は許可しません。

問題点

 ATSの設定によりますが、URLSessionのdownloadTaskがブロックされる場合あります。ATSのAllow Arbitrary Loads in Web ContentのYES設定では現在のところWKwebviewしかhttp通信を認められていないので。URLsession用に個別で通信を許可する等の対処が必要になります。

改造等

 現在はapple用にタグが設置されたアイコンとog:imageしか読み込みませんが、icon等の一般的なものも読み込むようにするとより多くの場所でアイコンを取得できます。その場合複数の画像が上がってくることにりますが...

 apple用のwebアイコンを取得する際に複数のアイコンがあり、かつsizeが指定されている場合は最も大きな画像を取得しますが、それでは都合の悪い場合はJavaScriptの方にある判別部分を書き換えてください。(urlDidGet(customeWebView: , arrURL:)で配列が帰って来る理由はswiftの方で判別していた時の名残です) 

【Swift3】TableViewで簡単な設定画面を作る

 iPhoneの純正の設定画面はTableViewを使用して作られています。そしてこれと同じようなものをアプリケーション内でTableViewを駆使して作ることができます。最終的な完成図はこのようになります。

f:id:BegiGrammer:20170323063007p:plain

  空のViewControllerを用意し、TableViewとCellを貼り付けDelegateとDataSourceを設定、cellのidentifierを設定するところの説明は省略します。

f:id:BegiGrammer:20170323063349p:plain

  このようにTableViewのStyleをGroupedにします。するとこのようなStyleになります。

f:id:BegiGrammer:20170323063632p:plain

 コードはこんな感じ。今回はViewControllerを使わずにやっていますが、ViewControllerにTableViewを貼り付ける形でもOK。(StaticなTableViewだとできない) Overrideしなければ普通に使える。

 あとはコードのコメントを参考にして

 

追記 -2018/1/7-

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

        return 25

    }

でヘッダーとするViewの高さを調整する。

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        return UIView()

    }

 でString のヘッダーの代わりにUIViewのヘッダーを指定できる

高さを調整しずにViewをヘッダーに指定すると何故か0段目のヘッダーが表示されない。

 

参考というかほどんどパクリ元

www.edumobile.org

【Swift3】WKWebViewの使い方とロード後に呼び出されるメソッド

 iOS8.0からWKWebViewが追加され、現在よりセキュアで安定したWKWebViewの使用をAppleは推奨しています。WKWebViewはStoryBoard上でまだ扱えないのでコードを書いていく必要があります。

WKNavigationDelegateはwebViewが活動中に色々といじれる便利なプロトコルなので一度リリースノートを読んでおくといいでしょう。

WebKit | Apple Developer Documentation

今回はwebページのtitleを獲得するためにページのロード後に呼び出される func webView(WKWebView, didFinish: WKNavigation!) を使用しました。またhttpsとhttpのどちらにも対応する場合 Info.plist -> App Transport Security Settings -> Allow Arbitrary Loads in Web Content を YES にする必要があります。この設定でどちらもセキュアに通信できるのはiOS10以上のデバイスのみです。iOS9や8対応の場合は Allow Arbitrary Loads もYESにします。しかしこれはあまり推奨されない方法です。

2017/03/14現在iOS10のシェアは76%でiOS9のシェアは16%なのでそろそろアプリのサポートを切ってもいい頃合いだとは思います。

App Store - Support - Apple Developer

 webのページを戻したり進めたりする場合昔はScreen Edge Pan Gesture を設置して戻る際の挙動を書かなければいけませんでしたが、今は webView.allowBackForwardNavigationGestures = true にしておくだけで簡単に設定できます。

TabBarの使い方

環境 Swift 3, app for iOS10

 様々なアプリケーションで使用されるTabBarについて書いていきます。TabBarは例えばApple純正の時計アプリとかを想像してもらうとわかりやすいかもしれません。

f:id:BegiGrammer:20170312081145p:plain

 TabBarとはこのように下にいくつかのタブが並び画面を簡単に移動することができる機能です。複数の画面をあらかじめ読み込ませた状態で画面移動するため、ページ移動の負荷が軽くなります。また同じような機能をボタンによるSegueで実現しようとするとTabBarと比べて複雑になりがちです。

 StoryBoardとしてはこのような形になります。

f:id:BegiGrammer:20170312081914p:plain

  TabBarはこのようにメインのコントローラーで複数のページを制御する形です。メインとサブをつなぐSegueはRelationshipになります。

f:id:BegiGrammer:20170312082732p:plain

  あらかじめ出来合いのTabBarControllerがあるのでそこから始めると容易にTabBarを実装できます。新たにitem(子ページ)を追加する場合はViewController追加後Tab Bar Itemを置き、親ページとRelationshipのSegueで接続することで追加ができます。

f:id:BegiGrammer:20170312082703p:plain

 TabBarのアイコンは標準のアイコンのほか、Retinaディスプレイで60x60ピクセルの画像を設定することができます。この場合ファイルの名前の最後に@2xをつけてください。(例: example@2x.png) 画像の色は透明部分以外TabBarItemに設定した色で塗りつぶされ表示されます。(上のStoryBoardの画像の歯車のアイコンはもともと黒色でした)

f:id:BegiGrammer:20170312083357p:plain

  違うTabBarのアイテムを選択した時に、どれを選択中かの値を受け取ることができます。UITabBarDelegateスーパークラスに追加してください。また、tabBarのデリゲートとしてselfを選択しておいてください。

func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem){}

 item.nameで選択中のアイテムの名前を知ることができ、item.tagで設定したtagの数値を受け取ることができます。

 TabBarの操作によって既に読み込まれた違うページを表示する場合、子ページ内のClassである幾つかのメソッドが実行されます。

f:id:BegiGrammer:20170312082655p:plain

 TabBarのitemはを選択された時にこの図のように4つのappearとdisappearメソッドを繰り返します。すなわちviewDidLoadは最初の一回しか行われません。起動時にitem2などの最初に現れないページを読み込ませる場合は、私はloadViewIfNeededを使用しています。

もちろんですが、TabBarのページ変更はユーザーが頻繁に行う場合があるので、この4つにはなるべく軽い処理か条件付けにより最適最小のものを実行するようにする必要があります。(まあそんなに気にしないでも良いレベルですが・・・)

【Swift】キーボードの使い方あれこれ

 Swift3でiOSのキーボードを使う際に色々とセッティングできるのでまとめておきます。

 -キーボードのreturn(改行)ボタンを押した際に実行されるメソッド

StoryBoardを使わずに直接コードを入力することもできますが、簡単なので今回はStoryBoardを使います。

f:id:BegiGrammer:20170312045645p:plain

 コード上にDid End On ExitのActionFuncを作るだけ。これを使うとtextField.resignFirstResponder()を使うことなく自動的に閉まるようになります。

 

 -手動で閉める

上にも書きましたが、

textField.resignFirstResponder()

 で指定したtextFieldの編集を終え、returnを押した際に閉めることができます。

 

 -デフォルトでreturnになっているのを色々変える

textField.returnKeyType = UIReturnKeyType.search

これで色々とUIReturnKeyTypeのに色々変更可能です。

UIReturnKeyType - UIKit | Apple Developer Documentation

 現在YahooとかGoogleとかは消去されて選択してもSearchだけになっているようです。