iOS

...now browsing by category

 

iOSアプリのソースコードで「嘘だろ・・・」と思ったもの

土曜日, 12月 3rd, 2022

iOSアプリの仕事をやっていて、新規で作成するよりも既存のアプリの開発を引き継ぐことが多いのですが、ソースコードを見ていて思わず「嘘だろ・・・」と呟いてしまうようなものを紹介します。

この記事はEngineMaker界隈 Advent Calendar 2022 の3日目の記事です。

画面遷移をpushのみで行なっている

UINavigationControllerの画面遷移を全てpushで行なっていました。詳細画面に遷移する時だけではなく、元の画面に戻る場合もpushしていたのです。popしているところはありませんでした。

そのため画面を行ったり来たりすると次々に新しい画面のインスタンスが生成され、それらは消されでに画面スタックに積み重なっていき、やがてメモリ不足でアプリがクラッシュしてしまう、という状態でした。

一画面あたりのメモリ使用量が少なく(画面内の項目が少なかった)、また画面数も少なかったため、問題が発覚していませんでした。

【iOSアプリに詳しくない人に向けた解説】

特に詳細画面に遷移する場合など、UINavigationControllerクラスが使用されます。これは内部に表示された画面を保持するスタックを実装し、新しい画面に遷移する場合はpushで新しい画面をスタックに積み上げ、前の画面に戻る場合はpopで画面スタックから最後に表示された画面を取り外す、という方法を取ります。

このように今まで表示された画面のインスタンスが保持されていることにより、前の画面に戻る場合に画面インスタンの生成(とてもコストがかかる)をせずに素早く戻ることができます。

リスト表示画面をUIScreenViewで実装している

リスト画面が全てUIScrollViewで実装されていました。UITableViewは使用されていませんでした。

そのアプリにはいくつかのリスト画面があるのですが、ほとんど1ページ分くらいの項目しかなく、特に問題とされていませんでした。しかし、3ページ分くらいの項目があるリスト画面があり、そこのスクロールが異様に遅かったので調べてみたところ、全てUIScrollViewを使っていました。

【iOSアプリに詳しくない人に向けた解説】

リスト画面ではUITableViewを使用します。これは画面に見えている項目(以降セルと呼びます)の分だけインスタンスを生成し、スクロールさせた時に画面から見えなくなったセルのインスタンスを削除せずにストックしておき、新しく見えてきたセルとして再利用する仕組みになっています。

これにより、画面に見えている分のセルの分しかメモリを消費せず、また再利用することによってセルのインスタンスの生成(コストがかかる)を大幅に省くことができ、何万行もあるようなリストでもヌルヌルサクサク動かすことができます。

Webなんかだと何万行もある場合は100行ごとにページを分けたりしますが、iOSでは上記の仕組みによりその必要はないのです。

iOS 14 で追加された「プライベート Wi-Fi アドレス」とは

水曜日, 9月 23rd, 2020

iOS 14 から「プライベート Wi-Fi アドレス」機能が追加されたそうです。これは Wi-Fi ネットワークごとに、ランダムな MAC アドレスを割り振る機能です。

以前は Wi-Fi 利用時に常に同じ MAC アドレスを使用していたため、街中の Wi-Fi を利用していると「一昨日サイゼリアにいた人と、昨日スタバにいた人と、今日ソフトバンクショップに来た人は同一人物だ」みたいな追跡が可能でした。今回の「プライベート Wi-Fi アドレス」を ON にすることで、これを防ぐ事ができます。

ただ、会社などで、Wi-Fi 接続時に MAC アドレスで認証している場合、Wi-Fi につながらなくなってしまいます。対処方法としては、(1) プライベート Wi-Fi アドレスを OFF にするか、(2) 職場の Wi-Fi に新しく割り振られた MAC アドレスで接続できるように管理部門に変更してもらう必要があります。

[iOS] スワイプバックキャンセル時のライフサイクル

日曜日, 6月 17th, 2018

iOSのUINavigationControllerにスワイプバックの機能がありますが、少しスワイプバックした時点で指を離してキャンセルした場合に、UIViewControllerのライフサイクルイベントがどのような順序で発生するか不明瞭だったので調べてみました。

使用したデバイスは iPhone 8 (iOS 11.3) です。

上から順番に時系列で並べてあります。
MasterViewControllerが親の画面、DetailViewControllerが子供の画面です。
DetailViewControllerが表示されている状態から始まり、スワイプバックでMasterViewControllerに戻ろうとしてキャンセルしています。

No. 操作 MasterViewController DetailViewController
1 少しスワイプ
2 viewWillDisappear
3 viewWillAppear
4 指を離す
5 viewWillDisappear
6 viewDidDisappear
7 viewWillAppear
8 viewDidAppear

画面表示時にデータを読み込んでいる場合は、

  • viewWillAppearで読み込み処理などを始めた場合は、viewWillDisappearまたはviewDidDisappearでキャンセルする。
  • viewWillAppearではなくviewDidAppearで開始する。

などの工夫が必要そうです。

AdMob on iPhone X

日曜日, 9月 24th, 2017

自分のアプリをiPhone Xのシミュレーターで表示してみたのですが、AdMobの部分がセーフゾーンに収まらないですね。AdMobをバージョンアップすれば出来たりするのかな?

【追記】
と思ったら、別のアプリだとちゃんとセーフゾーンに収まっている・・・
やはりフレームワークのバージョンかなー。
どこでバージョン見れるんだろう。

【さらに追記】
原因は私のミスでした・・・
ちゃんとセーフゾーンに収まっていたアプリは、AdMobのバナーをStoryboard上で定義していて、ちゃんと下端が Bottom Layout Guide に合うように設定していました。
一方、セーフゾーンからはみ出していたアプリは、AdMobのバナーをソースコード上で定義していて、しかも Autolayout を使わずに、viewController.view.frame の下端に合うように frameを設定していました。

AdMobのバナーをStoryboard上で定義していて、下端が Bottom Layout Guide に合うように設定したところ、セーフゾーン内に収まるように表示されました。

Xcode 7.1 Build Phase でドラッグ&ドロップが効かない

金曜日, 11月 13th, 2015

Xcode 7.1 にて Build Phase に項目を追加し、適切な位置にドラッグ&ドロップで移動しようとしたのですが、任意の位置に入らず戻ってしまいます。

スクリーンショット 2015-11-13 8.55.54

何度試しても上手くいかず、Xcodeを再起動しても、Macを再起動してもダメ。

同じような問題が起きている人はいないかと探してみたら、いました。

XcodeのRun Scriptのドラッグ&ドロップ移動のしにくさを緩和する

途中に入れるのは出来ませんでしたが、一番下に移動するのはできたので、入れたい位置の下から全ての項目を、一個ずつ最下行に移動することで、対処しました。

この人の場合は「非常に効きにくい」と言っていますが、私の場合、何度やっても成功しませんでした。

なんかコツとかあるんでしょうか?