アンドロイド版が、なかなか難しいので、先にiPhone/iPad版9VAeきゅうべえを作ることにした。その時のメモ。iPhoneXが画面の上に凹みができたので、メニューバーの場所を変えないといかん。画面を横にした時、今まではどちらの方向も同じだったが、凹みがどっちかで、変更しないといかん。カメラロールへの保存方法が変わってる・・・ Android版9VAeの開発記事はこちら
- iPhoneXのシミュレータを使うには、HighSierra にして、最新の Xcodeを入れないといかん
- カメラロールへの保存は、PHPhotoLibraryを使う
- Localize(多言語対応)
- ライブラリ作成
- プロジェクト管理に BitBucket を導入
- iPhone 11 対応
- bitcode 対応
- iCloud drive
- ファイルで読み込めるようにする(iOS11以降)
- ApplePencil対応
- NSURLConnection から NSURLSession への移行
- Downloadファイルを開く方法
- invalid context エラーの場所をさがす方法
- info.plistの多国語対応
- Mac Catalyst
- AppStoreへの登録手順
- 実機テストができたりできなかったりする
- M1 Xcode でシミュレータ用ライブラリを作る方法
- iOS 15 でカーソルキーが効かない問題
- iCloud対応
- iOS版にカラーピッカーをつける
- しゃべる機能をつける
- シェイクモーション
iPhoneXのシミュレータを使うには、HighSierra にして、最新の Xcodeを入れないといかん
- 凹みへの対応は、SafeArea を使う。
- StoryBoardの設定で、メニューバーはうまく行ったが、9VAeの独自ビューと、WebViewがうまくいかない。これは、プログラムで修正する。
ios - Objective C : How to create self.view inside Safe Area programmatically - Stack Overflow
- プログラムで修正するには、SafeAreaのサイズとデバイスの向きを知る必要があるが、普通の場所ではわからんらしい。
- メニューバーの項目の配置には、StoryBoard で、UIStackView に入れ、Distribution を「Fill Proportionally」に設定すると綺麗になった。複数のボタンをUIStackView に入れるには、複数のボタンを選んで、StoryBoardの右下のアイコン「Embed In」を押して何の中に入れるか選ぶとできる。なお、UIStackViewには描画機能がなく、背景に色をつけても無視される。
- StoryBoardで挿入した Viewをプログラムから変更するには、StoryBoardの名前とプログラム上の名前を対応づけしないといかん。それには、StoryBoard上のオブジェクトから右ボタンメニューを開き、「Referencing Outlets」の右側の+ボタンをドラッグし、Viewの上に持って行って対応するプログラムの中の名前と結ぶ。
- Viewを処理するプログラムには、インクルードファイル(.h)の中に、「@property (weak,nonatomic) IBOutlet Viewのタイプ 名前」という行と、プログラム(.m)の中に、「@synthesize 名前」が必要。IBOutlet の指定を元に、StoryBoard上で+ボタンをViewまでドラッグした時に、その名前が表示される。同じ名前にしておけば自動的にリンクされるというものではない。
- Viewをプログラムで操作する場合、画面の表示に反映されるのは、トップビューだけ。ボタンをつけたり消したりするのは、トップビューのプログラムでやらないといけない。
- WebView は、なぜか、画面配置をStoryBoardで制約をつけると描画されなくなった。プログラムでサイズ変更することはできた。
- iPhoneとiPadでもステータスバーの表示が違うみたいだ。ステータスバー有る無しでレイアウトを変えないといかん。
- StoryBoardでの制約のつけかた。(1)制約をつけたいViewを選ぶ。(2)
ボタン(3)左右はView、上下はSafeAreaを選ぶ(どのViewとの関係を制約にするか選べる)(4)最後に制約の追加ボタンをクリック。
- StoryBoardで制約をつけると、プログラムでViewのサイズ変更は不要になった。
カメラロールへの保存は、PHPhotoLibraryを使う
前からわかっていたが、ALAssetsLibrary が非推奨になって、PHPPhotoLibraryを使うことになった。iPhoneXシミュレータでアニメGIFをカメラロールに保存できなくなったので、対応する。
- 参考サイト
- GIFファイルは一旦自分のアプリ領域に作成する。それをカメラロールに転送する。
- UIImageを使って作成したGIFを転送すると静止画になってしまう。creationRequestForAssetFromImageAtFileURL にアニメGIFファイルのURLを指定すれば、アニメGIFを保存できた。
- エラーメッセージはGIF作成時とカメラロールへの転送時と異なる。メッセージ表示はボタンを押してから行うように作る。エラーコードを受け取って一か所でメッセージ表示するのではなく、各処理に分岐した最後にメッセージ関数を呼ぶ構造にする。
Localize(多言語対応)
- プロジェクトの設定で「Use Internatinalization」にチェックを入れる。すると、Base言語ができる。その後、+ボタンで Japaneseを追加。言語化用フォルダja.lproj, en.lproj ができる。
- Localizable.stringsは自動的にはできない。ja.lproj, en.lprojの中に infoPlist.stringsができているので、これを複製+リネームして、プロジェクトに追加する。
- @"xxx"をNSLocalizedString(@"xxx", comment: "") のように記述しておく。"xxx"="yyy";をLocalizable.stringsに入れておけば、"xxx"が"yyy"に置き換えられる。
ライブラリ作成
プロジェクト管理に BitBucket を導入
SouceTreeとの連携までややこしかったが、いろんな人に聞いて設定できた。
BitBucketはつぎのようにしてつかう。
- BitBucket(ネット上)にリポジトリを作る。リポジトリーはプロジェクトのいれもので履歴をもったフォルダみたいだ
- SouceTreeとの連携ができている場合、BitBucketから「SouceTreeにクローン」をつくれば、パソコン上に対応したフォルダが作られるみたいだ。フォルダの中を修正すれば、修正点がリストされるので(1)アップするものを index にあげる。(2)コミットボタン(3)プッシュボタン でネット上と同期される。
SouceTreeを使って新しい環境にクローンを作る方法
- SouceTreeをインストールして実行
- 「BitBucketクラウド」をクリック
- ATLASSIANに Googleアカウントでログイン>名前、メールアドレスが設定される>完了
- これで、BitBucketとSouceTreeが連携される。
- 取得したいリポジトリーを選んで「クローン」をクリック。
- フォルダ名を入力すればそこにクローンができる
iPhone 11 対応
iPhone11 に対応した Xcode にバージョンアップすると、ヘルプが表示されなくなった。UIWebView が使えなくなったようで、WKWebView に変更しないといかんらしい。
bitcode 対応
機械語をつくるまえの中間コードで、iPhoneアプリにはこれをつけて提出しないといかんらしい。これがあるといろんなCPU対応のコードをアプリストア側でつくれる。
iCloud drive
差替えリスト、命令リストを、9VAeフォルダに保存すると外部アプリから書き込めない。iCloud Drive をつかうと他のアプリから書き込めるかも
ファイルで読み込めるようにする(iOS11以降)
以下の対応をいれればファイルアプリでダウンロードからデータ転送できるみたい
ApplePencil対応
NSURLConnection から NSURLSession への移行
Deprecated対応
Downloadファイルを開く方法
- UIDocumentPickerViewController
info.plist内に以下を追加し値をYES
にするとファイルアプリでコピーできるようになるようだ
UIFileSharingEnabled
(Application supports iTunes file sharing
)LSSupportsOpeningDocumentsInPlace
(Supports opening documents in place
)
invalid context エラーの場所をさがす方法
- 実行中にコンテクストエラーメッセージがときどき発生した。このエラーが発生した場所をさがす方法は以下の記事が役に立った。
-
xCode左のナビゲーションエディタを、ブレークポイントのタブに切り替えて、
左下の+ボタンを押して、add symbolic breakpointを選びます
そしてSymbolに、CGPostErrorと入力
info.plistの多国語対応
- infoPlist.strings を各言語で作成。左側のキーワードは、info.plist の xml タグ名をかく
- 例:写真アクセス>
NSPhotoLibraryUsageDescription="写真の読み込み/GIF,MP4保存";
Mac Catalyst
Mac Catalyst に対応すると、Macでも動くようになる
AppStoreへの登録手順
Apple Connect で審査用紙を作成
- アプリを選ぶ
- iOS APP + をクリックし、次のバージョン番号を入力
- このバージョンの最新情報(日本語、英語)を入力
- プロモーション用テキストを前のバージョンからコピー(日本語、英語)
- Project > Target にバージョン番号を設定
- Project > archive を実行し、バージョンなどをチェック
実機テストができたりできなかったりする
- entitlement の中に Apple developement があると、テストできないが、このキーを除くとテストできることがあった。以下が関係しているかも?
-
What is a provisioning profile & code signing in iOS? | by Abhimuralidharan | Medium
- iPhone や iPad の OS バージョンをあげると、Xcode が未対応で実機デバッグできなくなった。macOS を Big Sir にあげたくない場合は、実機 iOS のバージョンをあげてはいけない。
M1 Xcode でシミュレータ用ライブラリを作る方法
- M1 Xcode でシミュレータで動作テストするとき、「i386, x86_64 がライブラリにない」エラーがでた場合、プロジェクト> Build Setting > Excluded Architectures に「i386 x86_64」を入れると実行できる。もともと シミュレータが Intel で動作していたため、Intel用コードを作成しようとして失敗しているもよう。Intel用コードを作らないように設定する。
- M1のシミュレータ用ライブラリは、arm でよいが、シミュレータと iOS用ライブラリは異なる。そのため違う名前で作成する。
- テストプロジェクトでは、iOSとシミュレータと異なる名前のライブラリをリンクする。その設定は、プロジェクト> General >Frameworks, Library で、iOS用ライブラリをシミュレータと実機で切り替える(どちらも iOSで両方書くことができない)XCFramework をつかうとできるらしい
iOS 15 でカーソルキーが効かない問題
- iOS 15 でカーソルキーが効かなくなった。以下のように wantsPriorityOverSystemBehavior の設定が必要。keyUp, keyDown, keyLeft, keyRight はキーを押したときの処理
- if (@available(iOS 11.0, *))をいれておかないと、iOS 10 で落ちた。
- 修正には、Xcode 13 (Big Sur以上)が必要
<修正前>
- (NSArray *)keyCommands { return @[ [UIKeyCommand keyCommandWithInput: UIKeyInputUpArrow modifierFlags: 0 action: @selector(keyUp)], [UIKeyCommand keyCommandWithInput: UIKeyInputDownArrow modifierFlags: 0 action: @selector(keyDown)], [UIKeyCommand keyCommandWithInput: UIKeyInputLeftArrow modifierFlags: 0 action: @selector(keyLeft)], [UIKeyCommand keyCommandWithInput: UIKeyInputRightArrow modifierFlags: 0 action: @selector(keyRight)] ]; }
<修正後>
- (NSArray *)keyCommands { UIKeyCommand *ukey = [UIKeyCommand keyCommandWithInput: UIKeyInputUpArrow modifierFlags: 0 action: @selector(keyUp)]; UIKeyCommand *dkey = [UIKeyCommand keyCommandWithInput: UIKeyInputDownArrow modifierFlags: 0 action: @selector(keyDown)]; UIKeyCommand *lkey = [UIKeyCommand keyCommandWithInput: UIKeyInputLeftArrow modifierFlags: 0 action: @selector(keyLeft)]; UIKeyCommand *rkey = [UIKeyCommand keyCommandWithInput: UIKeyInputRightArrow modifierFlags: 0 action: @selector(keyRight)]; if (@available(iOS 11.0, *)) if(@available(iOS 15.0, *)){ ukey.wantsPriorityOverSystemBehavior = YES; dkey.wantsPriorityOverSystemBehavior = YES; lkey.wantsPriorityOverSystemBehavior = YES; rkey.wantsPriorityOverSystemBehavior = YES; } return @[ ukey, dkey, lkey, rkey ]; }
iCloud対応
- 参考記事
- iOSでのファイル保存
- iCloud Documentをつかうのがよさそう。
- 有料のDeveloperAcountがないと開発できないらしい。Cloud capabilityを追加するみたい
iOS版にカラーピッカーをつける
しゃべる機能をつける
- AVSpeechSynthesizer < Macは、NSSpeechSynthesizer 。MacのNSSpeechSynthesizerはsleep(1)の間に動作するが、AVSpeechSynthesizerは動かない
- AVSpeechSynthesizer の出力をファイルにおとす方法(obj-c)
- 終了検出 デリゲートをつかう
シェイクモーション
- iPhoneをふるとメニューがON/OFFする機能をつけた。実装方法は以下の命令を ViewControrer にいれる
// シェイクモーションの開始を検知 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) { //NSLog(@"シェイクが開始されました。");ここに実行命令をいれる } } // シェイクモーションの完了を検知 - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) { //NSLog(@"シェイクが終わりました。"); } }