頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


申請時にXcodeでアップロードしたはずのファイルがApp Store Connectで反映されない

久々に新規アプリ(iOS)の申請を行った。
XcodeでArchiveし、Validateも通過しアップロード。
App Store Connectのビルドってところでアップしたファイルを選択しないと申請できない。
そしてアップロードしてApp Store Connectで見えるようになるまでにいくらかラグがあってそれこそメシでも食べてたらいいんじゃね?くらいに思ってたらいいことも経験上知っている。

ところが今回はそれが異様に長い。メシどころか筋トレして風呂に入ってたくさんのポケモンの個体値を調べててもまだ反映されないほどだった。

ここまで時間がかかるのは何か間違ってた、、、?

今回のアプリで何かやらかしてるとすれば初めての日本語のみのアプリ、ということだ。今までは大抵英語がメインで、ローカライズで日本語、というパターンが多かったのだが。
このあたりでまずいことになってんのかな?と思い調べ、、、
【Xcode】アプリのデフォルト言語を日本語に設定する方法 – 株式会社シーポイントラボ | 浜松のシステム開発会社
↑こちらなどを参考にして修正。
まだ申請してもいないのでver1.0は変えず、ビルド番号だけ1.0.0.1として再度アーカイブ、Validationも通してアップロード。

するとこれがすぐにApp Store Connectで反映された!

アップロード完了が21:50で
App Store Connectで見えたのが21:53だった。

あー、そのあたりがまずかったのかなあ?だったらビルド時なりvalidationで教えてくれればいいのに、とか思いつつとりあえず無事に申請。

App Store Connectで反映されたファイル

↑ところが翌日に確認すると最初にアップロードしたver1.0(1)が日付が変わった頃に到着してた。
アップロード完了時刻は17:19となっている。
17:19 → 翌日0:45に到着、、、

じゃあやっぱりアップロードが完了したファイルはラグがあるけど届くようになってんのかな?
つまり、App Store Connectで反映されない場合は、ただ待て!ということか。それもメシ食うだけじゃなくお風呂入って歯を磨いて寝てしまえ、というくらいで。


scrollViewをAutoLayoutとなるべく少ないコードで設定する例

なるべくstoryboard上でscroll viewとそこでスクロールするviewオブジェクトを設定するがviewに表示する内容はコードで作成する(自分の場合は表をコードで描く)。
なのでデバイスや表示する内容次第でviewオブジェクトの高さは変わるが、このような場合にAutoLayoutなどの指定はどうしたらいいのか?

自分の中では納得できる最小実装がこんなの。

scroll view(UIScrollViewオブジェクト)はstoryboardで好きに設定したらOK。これはええねん。問題は中身や。
実際に縦にスクロールするview(UIViewオブジェクト)をここではcontentViewとしておく。これをどうするか?だ。

まずstoryboard上ではscroll viewにcontentViewを乗せる。

Xcodeでのファイル構成1

↑Xcodeで見ると構成はこんなになってる。
ありがたいこと乗せるだけでこのviewがスクロールするビューだと認識してくれる。特にこれだよ!ってview controllerなんかで指定してやる必要もない。感心するわ。

問題のcontentViewのconstraintsだけど、、、

contentViewに設定するconstraints

↑これだけ。Superviewはもちろんscroll viewのこと。
・scroll viewとの上下左右はゼロですよって指定(A)
・横幅同じ
・高さは適当な数字
としている。(A)が感覚的に納得できないがそうするものだとXcodeが教えてくれた。

IBOutlet NSLayoutConstraint *contentViewHeightConstraint;
↑view controllerでこのようなconstraintに関係するoutletを用意しといて先ほどの適当な数字を指定したのと接続する。つまり、

Xcodeでのファイル構成2

↑高さを指定したconstraintを選択し、

outlet設定画面

↑通常通りここからNew Referencing Outletをにゅーっとドラッグして接続すればOK。constraintについてもこんな風に参照をコードに持ってこれるって最近知りました!


コード内でviewに乗せる内容を記述したとして、、、その一番下のy座標がわかったら、
contentViewHeightConstraint.constant = label2.bottom;
↑このようにその値を入れてやればよい。
この記述はviewDidLoadでOK。
これでiPhone 5sでもXS Maxでも意図通りに表示されました。
(個人的にはあまり使いたくない)viewDidLayoutSubviewsを使う必要もなし☺️


タブごとにstoryboardファイルを分ける

storyboardファイルを軽くするためxibを切り離す時のAutolayoutについて

↑この記事の訂正版。
いざこの方法で製品用のプロジェクトを新規作成して作っていくぞー!とはりきっていたのだが、、、あれ?だめやん?!となった。
ナビゲーション周りやテーブルのセルをタップした時にどうするのか、、、みたいなのってxibじゃあダメだったのだ。いや、なんとも情けない。

そんなわけで結局、タブごとにstoryboardファイルを分けることにした。

storyboardの設定

↑新規のstoryboardファイルにnavigation controller、view controllerなどをセット(これは3番目のタブ)。
見えにくいけど一番左がnavigation controllerで、その右がtable view controller。このテーブルのセルをタップすると右のview controllerが表示される、というもの。

-(void)setupTab3
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@“Tab3” bundle:nil];
naviCon3 = [storyboard instantiateViewControllerWithIdentifier:@“tab3_navi1”];
naviCon3.title = @“tab title3”;//タブのタイトル
naviCon3.tabBarItem.image = [UIImage imageNamed:@“icon_edit.png”];//タブの画像
}
↑storyboardのnavigation controllerをこんな感じで引っ張ってきて、、、
{
[tabBarController setViewControllers:
[NSArray arrayWithObjects:naviCon1 , naviCon2 , naviCon3 ,nil]];

[self addChildViewController:tabBarController];
[self.view addSubview:tabBarController.view];
}
↑それぞれtab bar controllerに入れる。

結果のスクショ1

↑この方法なら前記事のようなトリッキーなことをぜずともstoryboard内のSafe Areaもそのまま使える(文字列にはconstraintは設定していない、右下の四角で確認した)し、

結果のスクショ2

↑テーブルも意図通り表示された。


タブの画像やタイトル設定をコードで書く必要があるもののまあこれならわかりやすいだろう、ということでこれで書いていこう。不具合あったら訂正します。


storyboardファイルを軽くするためxibを切り離す時のAutolayoutについて

本記事はXcodeのstoryboadファイルをサクサクと開けるハイスペックなMacをお持ちの方には関係のない話です。😄

ウチの非力なMac minだとstoryboadファイルを表示させるのに少々時間がかかる。
プロジェクト作成時にできるMain.storyboardにどんどんと書き込んで行くと次第に表示までの時間も長くなってくる、、、(測ってないけど多分そうだろう)。

重いstoryboardファイル

↑クリックするのが億劫になってくる(でもしないわけにもいかん!)
storyboardファイルはGUIで扱うので仕方ないんだけどなんとかならないものか?

というこで分離できないか検討した。


今考えているのはタブバーを使うアプリなので、Main.storyboardではタブ周りの設定だけにする。
まず、Xcodeでタブバーアプリを選択し新規プロジェクトを作成する。するとタブを二つ持つプロジェクトができる。

重いstoryboardファイル

↑これはそれにFirstViewControllerにだけナビゲーションバーをかませたもの。

このFirstViewControllerをただのコンテナとし、そこに乗せるのをChildFirstViewControllerとする。

Xcodeのファイル作成画面

↑Xcodeでファイル作成時にxibも一緒に作成する(Also create XIB file)にチェックする。

Xcodeで作成されたファイル

↑するとこのように.hと.mファイルと共にxibファイルができる。
ここからの展開はこちらのxibファイルに書き込む。つまりタブごとにファイルが分かれるので、管理しやすくなるのでは!?と考えてる。

ところが問題はAutolayoutだ。

ChildFirstViewController.xibのsafe areaが使えるのか?

constraintを設定したview

↑確認のためChildFirstViewController.xibで上のように、safe areaの左上と右下に四角形、上部中央に文字列を表示するようなconstraintの設定をした(View as: iPhone XRで設定)。

そして以下のような単純な方法でコンテナ (FirstViewController)に乗せる。

// FirstViewController class
- (void)viewDidLoad
{
[super viewDidLoad];

ChildFirstViewController *childFirstVC = [[ChildFirstViewController alloc]
initWithNibName:@“ChildFirstViewController" bundle:nil];

[self addChildViewController:childFirstVC];
[self.view addSubview:childFirstVC.view];
}


失敗時の実行結果(iPhone 5s)

↑するとiPhone 5sではこのようにsafe areaが意図通りには伝わっていないことがわかる。


子側のviewサイズが親側のと同じにする簡単な方法はないものか、と調べると、、、

objective c - Autolayout constraints and child view controller - Stack Overflow

↑こういう記事を発見。やりたいこと同じやん!。
この記事の回答を参考にして以下のようにしてみた。
まず乗せる方。

// FirstViewController class
- (void)viewDidLoad
{

[super viewDidLoad];

ChildFirstViewController *childFirstVC = [[ChildFirstViewController alloc]
initWithNibName:@“ChildFirstViewController" bundle:nil];

[childFirstVC setupWithParentController:self];
}

↑作成したオブジェクトにselfを渡すのってどうよ、、、と思わないでもないがここは仕方ない。
次に乗る側。

// ChildFirstViewController class
-(void)setupWithParentController:(UIViewController *)parent
{
UIView *view = [self view];
[self willMoveToParentViewController:parent];
[parent addChildViewController:self];
view.translatesAutoresizingMaskIntoConstraints = NO;//—(1)
[parent.view addSubview:view];
[self didMoveToParentViewController:parent];

NSArray *horizontalConstraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-0-[view]-0-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(view)];
[parent.view addConstraints:horizontalConstraints];

NSArray *verticalConstraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-0-[view]-0-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(view)];
[parent.view addConstraints:verticalConstraints];
}

↑まあstackoverflowのままなんだけど、そのままだとXS Maxだといけるのに5sだとワーニングが吐かれて正常に表示されなかった。(1)を追加するといけた。

成功時の実行結果(iPhone 5s)

↑5sでの実行結果。よしよし!

成功時の実行結果(iPhone XS Max)

↑XS Maxでの実行結果。こっちもおっけー!

なお、上記constraintの設定後に、ChildFirstViewControllerの viewDidLoad: がコールされる。したがってここで初期設定を行えばよい。
これなら viewDidLayoutSubviews を使わないで実現できる(このメソッドはなるべく使いたくないのである)。

ということでこれでやってみる。不具合あったら追記する。



追記!↑これじゃダメだった!!!ので続きはこちら↓




アプリの画面を録画する(2)AVAssetWriterではまった話

アプリの画面を録画する(1)ReplayKitをあきらめた話
↑この続き。ReplayKitじゃなく自前でなんとかしよう!と調べてみた。

ios - How do I export UIImage array as a movie? - Stack Overflow
[Objective-C] 複数枚の静止画から動画を生成する - Qiita
↑このあたりを参考にさせて頂いた。

ところが作成してカメラロールに保存された動画ファイル(のスクショ)は

ずれて作成された動画ファイルのスクリーンショット

↑こんな感じで何やらずれている。ただし一応動画にはなってる。

あー、こういうずれはきっと、、、と予想した原因がことごとくハズレで結構はまった。
pixel formatの設定やアルファ値の扱い、CVPixelBufferRefを得る方法、カメラロールへの保存方法まで調べていたのだが。
ようやくわかったのは元の静止画像の横幅のサイズが16の倍数でないとダメ、ということであった。

【Swift 3】UIImageの配列から動画を生成する【AVAssetWriter】 | うるおいらんど
↑こちらの記事に書いてはいるけど、リファレンス、ヘッダーに書いてるのは見つけられなかった。

ちなみに元画像の横幅サイズが16の倍数でなくても、コード上でソース画像の横幅を16の倍数にしておけばそれなりに表示はしてくれた。縦横比の問題なんかはあるだろうけど。
縦方向は何ピクセルでもいいみたい。高さ457pxの画像で試したけどちゃんと動いた。457は素数らしい。




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.