2017年10月16日月曜日

iPhoneX対応

Flaskのアプリ達をiPhoneXの対応を着々と進めています。

iPhoneX向けレイアウトの条件


iPhoneX向けのレイアウトになる条件は、

  • XCode9(iOS11)でビルドしたアプリ
  • LaunchScreenがiPhoneXの対象になっている

ことらしい。
なので、XCode8(iOS10)でビルドしたアプリは、多分SafeArea部分が黒く塗りつぶされる...ハズ。
試せないので想像と期待ですが。

LaunchScreenは、Storyboardと画像Assetのどちらかを使うかを選べます。
Storyboardを使っていた場合は、対象になります。
画像Assetの場合は、iPhoneX用の画像を用意したら対象になります。


対応時に引っかかった所


Insets

画面の縦や横のサイズが変わってもピッタリとレイアウトされるようにコードからコンポーネントのサイズを変更したりしていた所の修正がいくつか必要だった。
手抜きでUIScreen.main.boundsの端末サイズから計算してたとことか、bottomLayoutGuideの量を考慮し忘れとかなど。

Insetsについては、Qiitaに記事を書いてみました。
iOS11のInsetsとLayout
誰かの助けになれば幸いデス。

Status Bar

Status Barを表示していなかったアプリも、iPhoneXだと表示したくなる。
だって、その領域が絶対にあるんですもの...!

なので、Status Bar有りに変えたアプリがいくつかあります。
ただ、やっぱり、iPhone8だと無しにしたい...というものもあって、切り分けたものもあります。
綺麗に切り分ける方法はないっぽいので、SafeArea.topがコレ以上だったら...というハードコーディングした。気持ち悪いけども、まぁしょうがないかなと。


画面下部にピッタリ置いたボタン


手が届きやすいので、画面下部にボタンをよく配置していたのですが、iPhoneXだと下にスペースができちゃうので、イマイチになってしまう。


この場合、ボタンの形状から考え直さないとなんともならなくて、左右にスペース開けて浮いた感じにしてみたり、角丸にしてみたり...とデザインの変更も。

そもそもの話として、iPhoneXは縦長なので画面下部が押しにくそうなのが悩ましい。
ぷにコンみたいなのが正解なのか。もう、ボタン無しUIへと時代は変わっていくのか...?!


Pushアニメーション時のズレ

NavigationBarが不透明だったり、Under Top Barのチェックをしていない時、UITableViewがズレてしまうという、よく話されている問題。
https://stackoverflow.com/questions/45573829/
バグであって、修正されると信じたいなぁ。このために回避のコードを入れたくない。

もう一つ、Pushアニメーション時に、TabBarが上に動いてしまうという問題がiPhoneXのみであって、これはBug Reportを書いた。

Push時のアニメーション関連は、まだ不安定な感じ。




iPhoneX対応は、制約を正しいGuideにコツコツとつなぎ直していく単純作業かと思いきや、デザイン合わないからどうしよう.... という悩みがでてくる。
iPhoneXはマイノリティだから とは思うものの、iPhoneXをメイン端末として使いたい私としては、えこひいき的に考えてしまう(笑)


あとは無事に実機をゲットできればよいのですがーー。




• • •

2017年10月2日月曜日

UIActivityViewControllerには罠がある

UIActivityViewController は画像やテキスト、URLなどを他アプリへ渡す仕組み。
Twitter, FacebookなどのSNSにシェアしてもらうときに使える。

実装はとても簡単。シェアしたいものを配列にして渡す。

let image:UIImage = ...
let shareItems:[Any] = [image,  "Hi!"]
let controller = UIActivityViewController(activityItems: shareItems, applicationActivities: nil)
present(controller, animated: true, completion: nil)

これで、以下のようなシートが表示される。


手軽なのでよく使っているのだが、罠がある。

1. 画像をシェアするときには、Usage Descriptionが必要


「Save Image」ボタンで、写真appに画像を保存できるのだが、その際にPhoto LibraryのUsage Descriptionが無いとクラッシュします。
写真appにアクセスしていないアプリだと見落としがちなので注意。

iOS10までは、Privacy - Photo Library Usage Description で読み込み/保存の両方ができましたが、iOS11からは書き込み時にはPrivacy - Photo Library Additions Usage Descriptionが必要です

Usage Descriptionは、Extension側で管理してよ と強く思います...!
「Save Image」はデフォルトで入っているものですが、3rd party appでもそうなのかどうかは試してないので不明。
どんなExtensionが使われるかはユーザ依存なので、アプリ本体側としては全部テストはできないから妥協が必要だが、ユーザー目線からみるとアプリのバグと見えるのでツライところ。

2. シェアアイテムが全て使われるとはかぎらない

アプリ本体側は、Image, Text, URLなど、シェアしたいアイテム を渡すが、それをどう使われるかはExtension次第。

たとえば、Facebookの場合、ImageとTextの両方を渡すと、Imageのみになる。
(現在の v143.0ではそうなるが、少し前のバージョンだとImageも認識されなかった)

FacebookはそもそもアプリからデフォルトのTextを入れてはダメというポリシーがあるようなので、Textは渡せない(渡さない)と考えたほうが吉。
ちなみに、Hashtag (ex. #Standland) はいけるようだ。

3. Extensionのアプリバージョンによって挙動がかわる

まぁ当たり前ではあるのですが、そういうものです。
言い換えると、実装したタイミングでは動いていたのに、今みたら動いていない...ということがあるということ。

iOS11のリリース直後はTwitterで画像のシェアができなくなった。
すぐTwitterのアプリをアップデートしてくれたので今はiOS11でできるようになったが、iOS10だと画像シェアできないようだ。 (Twitter v7.8)


4. iOS10のTwitter, Facebookはアプリ有無によって挙動がかわる

iOS10以前には、iPhone本体でTwitter, Facebookのアカウント管理機能があった(SocialFramework)。
そのため、アプリをインストールしていなくてもActivityViewControllerには表示され、シェアが可能。(これはiOS11で消滅)
つまり、iOS10で動作確認する際は、アプリインストール有無で挙動が変わるということを知っておくのが大事。



いろいろ気をつける注意するべき点はあるものの、UIActivityViewController + Extensionの仕組みはとてもいいものだと思う。

これがなければ、アプリに「他アプリへの連携機能」を付けてもらうしか無い。
マイナーアプリの場合は、連携機能を期待するのも難しいであろうし。

その代わり、使う方(本体アプリ)も、使われる方(Extension)も、正しい理解と実装をして、新しいOSにも対応し続けていかないといけない。

もし私が受託開発を請け負っている身だったら、あまり理解してもらえないようなお客さんの場合は、使うのはためらうかも...。



• • •