ラベル iOS の投稿を表示しています。 すべての投稿を表示
ラベル iOS の投稿を表示しています。 すべての投稿を表示

2024年10月14日月曜日

朝の目覚ましにプレイリストのランダム再生を使うオートメーションの設定

朝の目覚ましにプレイリストのランダム再生を使うオートメーションの設定

概要

忘れるのでメモ

環境

  • iPhone 14
  • iOS 18.0.1

アクションの内容

上から順番にアクション名は

  • 音量を設定
  • プレイリストを取得
  • ミュージックを検索
  • ミュージックを再生

最後に

iOS のバージョンによってアクション名の表記に若干違いがある可能性があるので注意です

参考サイト

2024年3月31日日曜日

iOS アプリを久しぶりにビルドしたときのメモ

iOS アプリを久しぶりにビルドしたときのメモ

概要

最終ビルドは 2021/7 頃のアプリになります
もともと Swift5 化はしていたプロジェクトになります

環境

  • Xcode 15.3
  • macOS 14.4.1

libarclite 対応

エラー

SDK does not contain 'libarclite' at the path '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a'; try increasing the minimum deployment target

対処方法

cocoapods などでインストールしたライブラリに対して行います
iOS Deployment Target を 12 以上にします
あまりメンテナンスされていないライブラリや古いライブラリの場合に発生します

  • Pods -> Project-> Build Settings -> iOS Deployment Target -> 12.0

ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES を inherited にする

エラー

cocoapods で表示される警告になります

[!] The `projectUITests [Debug]` target overrides the `ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES` build setting defined in `Pods/Target Support Files/Pods-project-projectUITests/Pods-project-projectUITests.debug.xcconfig'. This can lead to problems with the CocoaPods installation

対処方法

ビルド設定で ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES を $(inherited) を設定します

  • Target -> projectTests -> Build Settings -> Always Embed Swift Starndard Libraries -> $(inherited)

Sandbox オプションの無効化

エラー

データ保存系のライブラリで発生している気がします

Sandbox: rsync.samba(19313) deny(1) file-read-data /Users/user/Library/Developer/Xcode/DerivedData/project-bpovlgogrctpyxcxspcdgxydcxon/Build/Products/Debug-iphonesimulator/XCFrameworkIntermediates/Realm/Headers

対処方法

  • Project-> Build Settings -> User Script Sandboxing -> No

各種非推奨のコードなどの変更

Xcode が指摘してくれるおすすめ設定やコードリファクタを行いましょう

古いライブラリや存在していないライブラリの削除

例えば Firebase/AdMob はすでに存在していません
存在していないのですがなぜか使えて使っている場合は古い Firebase/Core が使われてしまうので危険です
ちゃんと代替の Google-Mobile-Ads-SDK を使う必要があります

+  pod 'Google-Mobile-Ads-SDK'
-  pod 'Firebase/AdMob'

最後に

定期的にビルドするのが大事です

2024年1月26日金曜日

iOS12 でネットワーク共有に接続できない場合の対処方法

iOS12 でネットワーク共有に接続できない場合の対処方法

対処方法

設定 -> 一般 -> リセット -> ネットワーク設定をリセット

で再度接続してみてください

環境

  • iPhone6 (12.5.7) 共有される側
  • iPhoneXR (17.12) 共有する側

2022年2月7日月曜日

StoryBoard で TableView にセクションを追加する方法

StoryBoard で TableView にセクションを追加する方法

概要

StoryBoard だけでテーブルビューにセクションを追加する方法を紹介します
追加されるセクションを固定セクションになるので動的に値を変更することは想定されていません

環境

  • macOS 11.6.2
  • Xcode 13.2.1

TableViewController を追加して StaticCells を設定する

  1. TableViewController を追加する
  2. TableView を選択し右ペインの三本線アイコンを選択
  3. Content を「Static Cells」に変更する
  4. Sections の数を変更する

これでビューのペインにセクションが追加されます

セクションのヘッダを変更

  1. 追加されたセクションを選択
  2. 三本線アイコンを選択
  3. Header を好きな文字列に変更

最後に

もし動的に値を変更したい場合はコード側でセクションを生成して TableView に追加するようなコードが必要になります

2021年10月29日金曜日

iOS アプリのレビューを curl で取得する方法

iOS アプリのレビューを curl で取得する方法

概要

公開している iOS アプリにレビューが評価があっても通知されません

基本的には自分で定期的にチェックするしかありません
公開しているアプリであれば公式で評価とレビューを取得するためのフィードが準備されているのでそれを使うと楽です

XML と JSON のメディアタイプで取得できます

環境

  • macOS 11.6
  • フィード 2021/10/04 時点

アプリID の取得

App Store Connect などで取得できます

App Store Connect -> アプリ選択 -> 一般 -> App 情報 -> AppleID

URL にも表示されているのでそこから取得しても OK です

xml

1234567890 の部分は取得したアプリID に変更してください

json

1234567890 の部分は取得したアプリID に変更してください
json の場合は一番後ろのパスを json に変更するだけです

2021年4月27日火曜日

対策方法 Guideline 2.2 - Performance - Beta Testing

対策方法 Guideline 2.2 - Performance - Beta Testing

概要

スクリーンショットやアプリ内の文章に test や demo などのフレーズが含まれると「Guideline 2.2 - Performance - Beta Testing」でリジェクトされます
今回は自分の対策方法を紹介します

環境

  • Swift5
  • Xcode 12.4 (12D4e)

スクリーンショット内に Test などの文字が含まれていてもダメ

審査時にはアプリのスクリーンショットを含める必要がありますが、そのスクリーンショット内で「test」などのフレーズが使われていてもダメになります
例えばテキストフィールドなどでユーザを登録する場合に「testuser01」などを使ってスクリーンショットを取得した場合でもアウトになります
意味合いが違くても「test」というフレーズが含まれているのでリジェクトされるので使わないようにしましょう

Admob のテスト広告でもダメ

シミュレータで Admob を取得すると「Test mode」という文字が広告に含まれます
これもリジェクトされるようなのでアプリ内に広告がありかつシミュレータを使っている場合は広告が表示されないようにしてスクリーンショットを撮影しましょう

2020年6月2日火曜日

Firebase のプッシュ通知に APNs 認証キーを使用する方法

概要

Firebase でプッシュ通知を送信するのに証明書ではなく認証キーを使って送信することができるようになりました
認証キーを使うことで証明書にあった期限切れなどが発生しないため更新作業が不要になります

環境

  • Firebase (2020/06/01 時点)
  • Apple Developer Portal (2020/06/01 時点)

プッシュ通知用の Key の作成

  • https://developer.apple.com/account/resources/certificates/list にアクセス
  • 「Keys」に移動
  • 「Create a key」を選択
  • 「Key Name」を入力 -> 「Apple Push Notifications service (APNs)」を選択 -> 「Continue」を選択 -> 「Registre」を選択
  • 「Download」を選択し p8 ファイルがダウンロードできたことを確認する

p8 ファイルは一度だけダウンロードできるのでしっかり保存しておくこと

Firebase にアップロード

  • Firebase のコンソールにログイン
  • 左上の歯車から「プロジェクトを設定」を選択
  • 「クラウドメッセージング」タブを選択
  • キーをアップロードするアプリを選択し「APNs 認証キー」から p8 ファイルをアップロード

Tips

KeyID と TeamID は Devloper Portal で確認できます
https://developer.apple.com/account/resources/authkeys/list

Firebase でアプリに TeamID を事前に設定しておく必要があります
「プロジェクトを設定」->「全般」-> (アプリ選択を選択) -> 「チームID」を編集すれば OK です

最後に

APNs 認証キーを作成し Firebase に登録する方法を紹介しました
UI などはいろいろと変更になるのでボタンの名前などが変わっている場合があるのでご注意ください

これとは別に AppID やプロビジョニングプロファイルなどは Developer Portal で作成する必要があるので作成しておきましょう

参考サイト

2019年4月12日金曜日

RubyMotion 環境構築

概要

RubyMotion にはフリープランがあり今回はそれを使ってみました
とりあえず環境の構築をしてみました

環境

  • macOS 10.14.4
  • Xcode 10.2 (10E125)
  • RubyMotion 6.1

RubyMotion インストール

まずは RubyMotion をインストールしましょう
このページからユーザ情報を登録すると zip ファイルがダウンロードできます

情報登録できれば OK です

RubyMotion Installer.zip というファイルがダウンロードできるので解凍しましょう
また同時に登録したメールアドレスにライセンスキーが送られるので確認します

  • unzip "RubyMotion Installer.zip"

解凍すると RubyMotion Installer.app が作成されます
ダブルクリックしてインストーラを起動します

Continue で次に進みます

EULA に同意します

ここでメールアドレスに送信されたライセンスキーを入力します
結構長いのでコピペで入力しましょう

あとはインストールされるのを待ちましょう

インストールが完了すると以下のようになります

同時に motion コマンドが使えるようになってるのでターミナルで確認しましょう

  • motion --version

テンプレートの WARNING が出る場合は新しいテンプレートをダウンロードしておきましょう

  • motion repo

Hello World

それではアプリを作成してみます
公式の通り進めてみました

まずはプロジェクトを作成しましょう

  • motion create hello

Gemfile やら Rackfile やらが作成されます
rake が必要になるのでインストールしましょう

  • bundle install --path vendor

タスク一覧を確認してみましょう

  • bundle exec rake -T

とりあえずシミュレータを起動してアプリを動かしてみます

  • bundle exec rake

これでビルドが始まり、ビルドが成功するとシミュレータにアプリにインストールがされ起動します

Tips

tmux 環境だと reattach-to-user-namespace が必要になるのでインストールして conf ファイルに記載しましょう

  • brew install reattach-to-user-namespace
  • echo 'set-option -g default-command "reattach-to-user-namespace -l $SHELL"' >> ~/.tmux.conf

実は

以下のエラーになりビルドできませんでした、、
もしかすると 10.14.4 はまだ動作しないのかもしれません

================================================================================
The application terminated. A crash report file may have been generated by the
system, use `rake crashlog' to open it. Use `rake debug=1' to restart the app
in the debugger.
================================================================================
rake aborted!
TypeError: no implicit conversion from nil to integer
/Users/hawksnowlog/.rubymotion/rubymotion-templates/motion/project/template/ios.rb:235:in `exit'
/Users/hawksnowlog/.rubymotion/rubymotion-templates/motion/project/template/ios.rb:235:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:273:in `block in execute'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:273:in `each'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:273:in `execute'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:214:in `block in invoke_with_call_chain'
/usr/local/Cellar/ruby/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:194:in `invoke_with_call_chain'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:238:in `block in invoke_prerequisites'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:236:in `each'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:236:in `invoke_prerequisites'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:213:in `block in invoke_with_call_chain'
/usr/local/Cellar/ruby/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:194:in `invoke_with_call_chain'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/task.rb:183:in `invoke'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/application.rb:160:in `invoke_task'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/application.rb:116:in `each'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/application.rb:116:in `block in top_level'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/application.rb:125:in `run_with_threads'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/application.rb:110:in `top_level'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/application.rb:83:in `block in run'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/application.rb:186:in `standard_exception_handling'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/lib/rake/application.rb:80:in `run'
/usr/local/lib/ruby/gems/2.5.0/gems/rake-12.3.2/exe/rake:27:in `<top (required)>'
/usr/local/bin/rake:23:in `load'
/usr/local/bin/rake:23:in `<main>'
Tasks: TOP => default => simulator

参考サイト

2019年1月18日金曜日

fastlane 入門 (スクリーンショットを自動で取得してみる)

概要

fastlane は iOS/Android 用に作られたワークフローツールです
アプリのビルドからリリースまでを一貫して行えます
今回はインストールと簡単な動作確認を行ってみました

環境

  • macOS 10.14.2
  • fastlane

fastlane インストール

  • brew cask install fastlane
  • export PATH="$HOME/.fastlane/bin:$PATH"

他にも rubygems でインストールしたり xcode-select でもインストールできます
お好きな方法でインストールしてください
brew インストールの場合は PATH に fastlane コマンドを追加します

初期化

  • cd /path/to/project
  • fastlane init

で対話式の初期化が始まります
今回はスクリーンショットを自動で取得するレーンを作成しました
以下はログです

[11:27:24]: Created new folder './fastlane'.
[11:27:24]: Detected an iOS/macOS project in the current directory: 'ios-200s-games.xcodeproj'
[11:27:24]: -----------------------------
[11:27:24]: --- Welcome to fastlane  ---
[11:27:24]: -----------------------------
[11:27:24]: fastlane can help you with all kinds of automation for your mobile app
[11:27:24]: We recommend automating one task first, and then gradually automating more over time
[11:27:24]: What would you like to use fastlane for?
1. Automate screenshots
2. Automate beta distribution to TestFlight
3. Automate App Store distribution
4. Manual setup - manually setup your project to automate your tasks
?  1
[11:27:32]: -------------------------------------------------------                                                            
[11:27:32]: --- Setting up fastlane to automate iOS screenshots ---                                                            
[11:27:32]: -------------------------------------------------------                                                            
[11:27:32]: fastlane uses UI Tests to automate generating localized screenshots of your iOS app                                
[11:27:32]: fastlane will now create 2 helper files that are needed to get the setup running                                   
[11:27:32]: For more information on how this works and best practices, check out                                               
[11:27:32]:     https://docs.fastlane.tools/getting-started/ios/screenshots/                                                   
[11:27:32]: Continue by pressing Enter
[11:28:46]: Parsing your local Xcode project to find the available schemes and the app identifier
[11:28:46]: $ xcodebuild -showBuildSettings -project ios-200s-games.xcodeproj
   Successfully created SnapshotHelper.swift './fastlane/SnapshotHelper.swift'
   Successfully created new Snapfile at './fastlane/Snapfile'
-------------------------------------------------------
Open your Xcode project and make sure to do the following:
1) Add a new UI Test target to your project
2) Add the ./fastlane/SnapshotHelper.swift to your UI Test target
   You can move the file anywhere you want
3) Call `setupSnapshot(app)` when launching your app

  let app = XCUIApplication()
  setupSnapshot(app)
  app.launch()

4) Add `snapshot("0Launch")` to wherever you want to trigger screenshots
5) Add a new Xcode scheme for the newly created UITest target
6) Add a Check to enable the `Shared` box of the newly created scheme

More information: https://docs.fastlane.tools/getting-started/ios/screenshots/
[11:28:48]: If you want more details on how to setup automatic screenshots, check out
[11:28:48]:     https://docs.fastlane.tools/getting-started/ios/screenshots/#setting-up-snapshot
[11:28:48]: Continue by pressing Enter
[11:29:14]: Which is your UI Testing scheme? If you can't find it in this list, make sure it's marked as `Shared` in the Xcode scheme list
1. ios-200s-games
?  1
[11:29:37]: ------------------------------------
[11:29:37]: --- Automatically upload to iTC? ---
[11:29:37]: ------------------------------------
[11:29:37]: Would you like fastlane to automatically upload all generated screenshots to App Store Connect
[11:29:37]: after generating them?
[11:29:37]: If you enable this feature you'll need to provide your App Store Connect credentials so fastlane can upload the screenshots to App Store Connect
[11:29:37]: Enable automatic upload of localized screenshots to App Store Connect? (y/n)
n
[11:35:46]: It looks like your project isn't set up to do automatic version incrementing
[11:35:46]: To enable fastlane to handle automatic version incrementing for you, please follow this guide:
[11:35:46]:     https://developer.apple.com/library/content/qa/qa1827/_index.html
[11:35:46]: Afterwards check out the fastlane docs on how to set up automatic build increments
[11:35:46]:     https://docs.fastlane.tools/getting-started/ios/beta-deployment/#best-practices
[11:35:46]: --------------------------------------------------------
[11:35:46]: ---    Successfully generated fastlane configuration ---
[11:35:46]: --------------------------------------------------------
[11:35:46]: Generated Fastfile at path `./fastlane/Fastfile`
[11:35:46]: Generated Appfile at path `./fastlane/Appfile`
[11:35:46]: Gemfile and Gemfile.lock at path `Gemfile`
[11:35:46]: Please check the newly generated configuration files into git along with your project
[11:35:46]: This way everyone in your team can benefit from your fastlane setup
[11:35:46]: Continue by pressing Enter
[11:36:06]: fastlane will collect the number of errors for each action to detect integration issues
[11:36:06]: No sensitive/private information will be uploaded, more information: https://docs.fastlane.tools/#metrics
[11:36:06]: ----------------------
[11:36:06]: --- fastlane lanes ---
[11:36:06]: ----------------------
[11:36:06]: fastlane uses a `Fastfile` to store the automation configuration
[11:36:06]: Within that, you'll see different lanes.
[11:36:06]: Each is there to automate a different task, like screenshots, code signing, or pushing new releases
[11:36:06]: Continue by pressing Enter
[11:36:18]: --------------------------------------
[11:36:18]: --- How to customize your Fastfile ---
[11:36:18]: --------------------------------------
[11:36:18]: Use a text editor of your choice to open the newly created Fastfile and take a look
[11:36:18]: You can now edit the available lanes and actions to customize the setup to fit your needs
[11:36:18]: To get a list of all the available actions, open https://docs.fastlane.tools/actions
[11:36:18]: Continue by pressing Enter
[11:36:25]: ------------------------------
[11:36:25]: --- Where to go from here? ---
[11:36:25]: ------------------------------
[11:36:25]: Learn more about how to automatically generate localized App Store screenshots:
[11:36:25]:             https://docs.fastlane.tools/getting-started/ios/screenshots/
[11:36:25]: Learn more about distribution to beta testing services:
[11:36:25]:             https://docs.fastlane.tools/getting-started/ios/beta-deployment/
[11:36:25]: Learn more about how to automate the App Store release process:
[11:36:25]:             https://docs.fastlane.tools/getting-started/ios/appstore-deployment/
[11:36:25]: Learn more about how to setup code signing with fastlane
[11:36:25]:             https://docs.fastlane.tools/codesigning/getting-started/
[11:36:25]: 
[11:36:25]: To try your new fastlane setup, just enter and run
[11:36:25]: $ fastlane screenshots

途中で iTunesConnect にアップロードするか聞かれますがそれは NO にしました

Xcode 側の準備

init 時にコード側で設定してほしいことが表示されているのでそれを設定するだけです
必要なファイルを配置したりコードを変更します

まず UITests のグループ配下に生成された fastlane/SnapshotHelper.swift を配置します
fastlane1.png

そして UITests のテストコード setup を以下のように変更します

override func setUp() {
    continueAfterFailure = false
    let app = XCUIApplication()
    setupSnapshot(app)
    app.launch()
}

更にテスト実行時にスクリーンショットを取得したい箇所で screenshot メソッドをコールします
スクリーンショットを取得した画面分挿入してあげると良いでしょう
0Launch の部分は好きな名前を入力することができます

func testExample() {
    snapshot("0Launch")
}

fastlane2.png

これでスクリーンショットを取得するための準備は完了です

実行

  • fastlane screenshots

でスクリーンショットの取得が開始されます
デフォルトでは以下のデバイスのスクリーンショットが取得されます

  • iPhone 7
  • iPhone 7 Plus
  • iPhone 8
  • iPhone 8 Plus
  • iPhone X
  • iPhone XS
  • iPhone XS Max
  • iPhone XR
  • iPad (5th generation)
  • iPad Pro (9.7-inch)
  • iPad Pro (12.9-inch)
  • iPad Pro (10.5-inch)
  • iPad (6th generation)
  • iPad Pro (11-inch)
  • iPad Pro (12.9-inch) (3rd generation)

実行中はヘッドレスでシミュレーターが起動するのでマシンに結構な負荷がかかるのでご注意ください

かなりログが表示されるので省略しますが以下のように時間が表示されれば完了です

[11:19:32]: fastlane.tools just saved you 14 minutes!

HTML ファイルとスクリーンショットは fastlane/screenshots/en-US/ に保存されブラウザで結果を表示してくれます

レーンを独自に定義する

fastlane/ ディレクトリ配下に各種設定ファイルがあります

Appfile
Fastfile
Snapfile
SnapshotHelper.swif

これをカスタマイズすることでスクリーンショットを取得する以外のことができるようになります
ちなみに今回は fastlane screenshots コマンドを定義しまし実行しましたが実行可能なコマンドの一覧を表示するには

  • fastlane list

を実行します
また DSL として実際に使えるアクションの一覧を表示する方法は

  • fastlane actions

で表示できます
この一覧に capture_screenshots というアクションがありこれを fastlane/Fastfile で使って lane: screenshots として DSL で定義することでコマンドが使えるようになります

最後に

fastlane でスクリーンショットを自動取得してみました
init コマンドを使えば雛形は作成してくれるので簡単に始められます

あとはドキュメントとアクションを見ながら自分で Fastfile をカスタマイズすれば好きなビルドフローを作成することができます
slack というアクションもあるのでフロー終了後に通知したりすることもできます

Xcode Server などを個別で立ててやるよりも fastlane 対応すれば Travis CI や Circle CI でも動かすことができるので将来的にも幸せになれると思います

参考サイト

2017年8月26日土曜日

個人的 App Previews とスクリーンショットの作成方法

概要

アプリを審査に出す時に必要になる動画 (App Previews) とスクリーンショットを取得するコツを紹介します
自分は実機を使わずにすべてシミュレータを使っています

環境

  • macOS X 10.12.6
  • Xcode 8.3.3 (8E3004b)
  • iMovie 10.1.6

流れ

  1. iPhone 7 Plus のシミュレータでスクリーンショット取得
  2. iPhone 7 Plus のシミュレータで動画撮影
  3. iPad Pro (12.9-inch) のシミュレータでスクリーンショット取得
  4. iPad Pro (12.9-inch) のシミュレータで動画撮影
  5. 2, 4 で撮影した動画を iMovie の App Previews モードで編集 (音を何処かに必ず入れること) -> 書き出し

で、できた成果物を iTunes Connect にアップロードします
動画撮影はシミュレータを使っています
他のデバイスサイズに関しては iTunes Connect の設定で使いまわすことができるので使いまわします
iMovie で動画を書き出す際には 30 秒以内の動画になっていることを確認してください

最後に

App Previews とスクリーンショットを取得するコツを紹介しました
現時点ではこの方法でやることでアプリに必要な情報を作成することができると思います

2017年7月4日火曜日

「Guideline 4.2.2 - Design - Minimum Functionality」に対抗してみました

概要

アプリの審査基準の一つに Minimum Functionality という基準があり、これはアプリが単純すぎる場合にリジェクトされる基準になります
例えば Web ビューだけのアプリでサイトに訪問するのと同じエクスペリエンスしか提供されていない場合などは対象となります
今回この基準でリジェクトされたアプリがあり、リジェクトされるごとに機能を少しづつ改善したところリジェクトされないところまで来たので、その対処方法を紹介します

環境

  • macOS X 10.12.5
  • Xcode 8.3.3 (8E3004b)

アプリの概要

アプリは単純な RSS リーダのようなアプリです
ある特定のサイトに特化した RSS リーダでアプリで見栄えを良くし簡単に見れるようにしたアプリです
基本的にな機能はフィード情報を取得して UITableView で表示するだけなので確かに Web ビューと変わらないと言えば変わりません

あえて言うなら売りはシンプルさですが、今回 Minimum Functionality に引っかかりました

対応方法

具体的に「これ」を実装すればリジェクトされないという基準もわからないのでとりあえず思いつくものを機能追加してみました
一応選定基準としては

  • UI に大きく影響しない機能
  • コードレベルで簡単に追加できる機能

あたりを基準に選定していきました

とりあえず普通に出してみる

リジェクトされたあとにコメントでアピールしてどうなるか確認してみました
アピールコメントの内容は「Web に訪問するよりシンプルで良い、見やすい」という点をアピールしました

が結果は当然アウトでリプライはガイドラインの URL がびっしりと書かれた感じでした

プッシュ通知の実装

Firebase を使ってプッシュ通知機能を入れてみました
UI に影響がなくプッシュ通知だけであれば、ロックインもほぼされないので導入しました

で、結果はこれもダメ
今回アピールはせずコメントに「じゃあアプリのスピードを改善するのじゃダメ?」という質問にしてみました
要するにどうやればリジェクトされないか具体的な方法を教えてくれるか期待したですが
結局リプライは前回と同様ガイドラインの URL が送られてくるだけでした

画像のキャッシュ機能を実装

ならばと実装してみようということで画像を取得する際にメモリにキャッシュする機能を実装してみました
具体的には Kingfisher というライブラリを追加することでキャッシュできるようにしました
(Kingfisher の紹介記事はこちら)

で、結果はこれもダメ
たぶんここまでの結果を見て自分の予想だと内部的なブラッシュアップや機能改善ではダメで UI 的に変化をもたらして UX を向上しないとダメなんだろうなと思いました (もちろんアプリによっては機能改善でも OK かもしれませんが)

ここではアピールやコメントは一切せず次の一手を考えてました

CoreData を使ってお気に入り機能を追加する

読み込んだフィードの情報をお気に入りできる機能を追加しました
お気に入りの情報は CoreData を使ってローカル端末にのみ保存します
クラウド等で保存はしないのでアプリが消えればお気に入りの情報もクリアされてしまいます
お気に入りは UITableViewCell をスワイプすることでできるようにしました
スターボタンを設置しても良かったのですが、既存 UI への影響を考えて極力変更が小さい方法を選択しました

で、結果的にこれがヒット、アプリの審査が通りました
ここまでの結果で見れば CoreData を使った機能を追加すれば回避できるような気がします
が、やはりアプリによってだとは思うので正直 CoreData の機能が決め打ちになるとは思えないかなと思います
が、試してみる価値はあるかなと思います

別の観点から

実は画像のキャッシュ機能を追加した時に、ちょうどよかったので別のアプリにも Kingfisher を追加しました
で、実はその別のアプリも Minimum Functionality で引っかかったのですが、そのアプリはアピールしたところすんなり審査を通過しました
アピールした点は画像のキャッシュを追加したという点ではなく「Web ビューじゃないよ、サイトじゃ同じ内容確認できないよ」という内容なので何とも言えませんが
アピールを頑張ってすれば、アプリによっては審査が通過するアプリもあるのかもしれません

アプリの審査基準は正直わからない

何度もアプリを審査に出してはいますが、明確な審査基準はさっぱりわかりません
ガイドラインはあるものの結局人がレビューしているので人によって審査基準に差がある気もしています

というのも今回審査が通ったときに別のアプリも審査中だったのですが、別のアプリもすべて同日に審査が通りました
ここから予想するに自分のレビュー待ちのアプリすべてをレビューしてくれるある 1 人の人が指定され、その人が結構ゆるい方でバンバン審査が通過したんじゃないかなとも予想しています

というかアプリの審査はアプリごとのキューじゃなくてユーザごとのキューになっているような気もしました
1 番最初にレビュー待ちになったアプリは一週間前で最後にレビュー待ちになったアプリは 2 日前だったので、それで同日に審査が通ったのを見るとそういうこともあるのかなと思った次第です

最後に

Minimum Functionality の対策を紹介しました
自分の場合、決め手は CoreData の機能でしたが、必ずしも CoreData を使った機能を追加することで通過するようになるとはならないと思います
それでも、そういうケースがあるということを紹介できて良かったかなと思います

もしかしたら全く同じ機能で Swift4 対応したアプリを審査に出したらまた Minimum Functionality でリジェクトされるかもしれませんが、、、w

2017年5月25日木曜日

au SIM ロックの iPhone5 を復活させたのでメモ

概要

すごい昔に au で契約した SIM ロックな iPhone5 が眠りについていたので復活させてみました

環境

  • macOS 10.12.4
  • docker 17.05
  • docker registry 2.6.1

なぜ眠りについてしまったのか

iOS9 の時代に 2 年縛りが終了し au は解約しました
その後 Wifi のみで使い続けていたのですが、その時に iOS9 から iOS10 にアップグレードしました
iOS10 にアップグレードした際に iPhone のアクティベーションが必要でその際に実は SIM カードが必要でした
そのことを知らず au 解約時に SIM カードを捨ててしまったため iPhone5 は眠りについていました

その後いろいろと調べると解約済みでもいいので au の SIM カードがあればアクティベーションはできることを知り復活させることにしました
家族用の au SIM カードをありそれで SIM カードは代用しています

手順

電源が入らない

ずっと眠りについていたのでバッテリーが空になっていました
ライトニングでとりあえず充電していると勝手に起動し始めました

iPhone5 はバッテリーが空の場合、充電中であっても電源ボタンを押しても起動しません
なので、ある程度充電されるまで気長に待ちましょう

アクティベーション作業

SIM カードを挿しましょう
SIM カードは解約している SIM カードなので、通信はできません
なので変わりに Wifi を設定します
アクティベーションの途中で Wifi を設定するところがあるので設定します
すると Wifi で iPhone5 のアクティベーションが完了します

その後 AppleID でログインするように促されます
AppleID が 2 ファクタ認証になっている場合はここでパスワード以外に 6 桁のコードでの認証も必要になります
基本的には同じ AppleID で使用している iPhone や Mac にコードが送られてくるのでそのコードを使います
(このとき別の端末がない人はどうなるんだろうと思いました、実は別端末がなく 2 ファクタ認証をオンにしている人はここで詰んでしまうのだろうか、、、)

アクティベーションが完了し起動したあとは iPhone の初期化を行います

初期化

アクティベーション後は前回の iPhone の状態で起動します
今回自分は完全に初期化 (工場出荷時に初期化) したかったのでリセット作業を行いました

  • 設定 -> 一般 -> リセット -> 初期化 -> すべての設定をリセット
  • 設定 -> 一般 -> リセット -> 初期化 -> すべてのコンテンツと設定を消去

でリセットします
下が完全リセットなので、下だけ実行すればいいかもしれません
リセット後は起動したら iPhone 自体の初期化から始まります

iPhone の初期設定

以下指示に従い設定していきましょう
また、この段階でも SIM を挿しておきましょう
完全に初期化しているので再度アクティベーションが走ります

  • 言語、タイムゾーンの設定
  • Wifi の設定
  • アクティベーション (wifi で失敗する場合は何度か繰り返す)
  • GPS 設定
  • パスワード設定 (iPhone5 のためタッチ ID の設定はなし)
  • AppleID でログイン、2 ファクタ認証でログイン

であとは iPhone にログイン後完全に初期化した状態で普通に使うことができます

最後に

アクティベーションできずにいた iPhone5 を復活させてみました
ポイントは「解約済みでもいいので SIM カードを挿す」ことでした

当然自宅に Wifi 環境がないと何もできませんが、Wifi があえば iPod touch 的な使い方は全然できます

2017年5月22日月曜日

iOS 証明書更新方法

概要

Apple から証明書の期限切れメールが来た際に行う更新作業の流れを備忘録として残りしておきます

環境

  • macOS 10.12.4
  • Xcode 8.3.2
  • Apple Developer (2017/05/22 時点)

CSR 作成

  1. キーチェーンアクセスを開く
  2. 左メニューから キーチェーンアクセス
  3. 証明書アシスタント
  4. 認証局に証明書を要求を選択

入力情報は以下の通り

  • ユーザのメールアドレス -> DeveloperProgram に登録しているメールアドレス
  • 通称 -> 何でもOK
  • CAのメールアドレス -> 空でOK
  • ディスクに保存にチェック
  • 鍵ペア情報を指定にチェック

保存先を選択

  • 鍵のサイズ -> 2048ビット
  • アルゴリズム -> RSA

で OK

Apple Developer に証明書を作成する

  1. DeveloperCenter にアクセス
  2. 証明書管理画面に移動
  3. Certificates を選択し右上の「+」を選択
  4. iOS App Development/App Store and Ad Hoc
  5. Continue
  6. Continue
  7. Chooes File
  8. 先ほど作成した CSR を選択
  9. Continue
  10. Done

証明書は Development 用 (iOS App Development) と Distribution 用 (App Store and Ad Hoc) を作成します

証明書は作成できたらローカルマシンに保存しましょう
そしてクリックしてキーチェーンアクセスに登録しておきます

Apple Developer のプロビジョニングプロファイルを編集する

  1. DeveloperCenter にアクセス
  2. プロビジョニングプロファイル管理画面に移動
  3. 既存のプロビジョニングプロファイルを選択
  4. Edit
  5. Certificates に先ほど作成した Distribution 用の証明書を選択
  6. Generated
  7. Done

存在するプロビジョニングプロファイル分編集しましょう
ここまで完了すれば更新作業は完了です

Tips

期限切れになった証明書は心配であれば期限切れ後に削除しましょう
キーチェーンアクセスに登録した証明書も同様です

キーチェーンアクセスに登録した証明書から p12 ファイルを書き出しておくと後々嬉しいかもしれません
別の Mac で開発する場合に必要になります
1 台の Mac で開発しているのであれば不要です

また更新後は特に Apple から完了の連絡は来ません
期限切れの通知はしてくれるのですが、更新完了はないようです

最後に

現段階での更新手順は以上です
仕組み的に大きく変わらないのであれば、今後もこの流れで更新できると思います

Apple Developer の管理画面がちょくちょく変わる可能性がありそうだったのでスクリーンショットはあえて掲載しないようにしました

たぶん証明書の更新に影響するのは公開用のアプリのビルドとプッシュ通知だけになるので、すでに公開しているアプリが動かなくなるということはおそらくないと思います
なので、プッシュ通知を使っていないのであれば更新しないくても OK なのかなと思います
自分はプッシュ通知は使っていませんが更新するようにしていますが

2017年2月28日火曜日

App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

概要

iOS 開発中 http に通信するシーンが何度もありその度にタイトルのエラーに悩まされては設定していたので忘れないようにメモしておきます

環境

  • Xcode 7.3.1
  • iOS 9.3.1

Xcode の Info.plist に NSAppTransportSecurity の項目を追加する

Info.plist を開いて項目を設定していきます

1 - Information Property List の横のプラスボタンをクリックする

set_ats_in_infoplist_1.png

2 - 新しく追加された行に NSAppTransportSecurity を入力します

set_ats_in_infoplist_2.png

3 - 追加した NSAppTransportSecurity 配下に更に NSAllowsArbitraryLoads を追加します

set_ats_in_infoplist_3.png

まず追加した NSAppTransportSecurity という項目は勝手に「App Transport Security Settings」という名前に変わります
その左の三角ボタンを下向きにします
次にその状態で「App Transport Security Settings」の右にあるプラスボタンをクリックします
最後に入れ子として追加された項目に NSAllowsArbitraryLoads を入力します

入れ子として項目を追加した段階で「App Transport Security Settings」の Type は自動的に Dictionary に変わります

4 - Type を「Boolean」Value を「YES」に設定します

set_ats_in_infoplist_4.png

追加した NSAllowsArbitraryLoads という名前はまた勝手に「Allow Arbitrary Loads」という名前に変わります
気にせずその横にある Type と Value を変更すれば OK です

最後に

本当は http としてアクセスするドメインごとに管理したほうがセキュリティ的にいいのですが、どうしても不特定多数のドメインにアクセスするアプリだとこうせざるを得ません

これでもう忘れることはないと思います、たぶん

2017年2月22日水曜日

WARNING ITMS-90080: "The executable 'Payload/myapp.app/Frameworks/NCMB.framework' is not a Position Independent Executable

概要

Xcode で iTunesConnect にビルドしてできたファイルをアップロードする際にタイトルの警告が発生しました
対処方法を紹介したいと思います

環境

  • Mac OS X 10.11.5
  • Xcode 7.3.1
  • Cocoapods 0.39.0
  • iTunes Connect 2016/06/07 時点

警告詳細

WARNING ITMS-90080: “The executable ‘Payload/myapp.app/Frameworks/NCMB.framework’ is not a Position Independent Executable. Please ensure that your build settings are configured to create PIE executables. For more information refer to Technical Q&A QA1788 - Building a Position Independent Executable in the iOS Developer Library.”

が全容です
Framework のところはどんな Framework でも出ると思います
この警告が Xcode で Product -> Archive としてビルドしたあとに iTunes Connect にアップロードするときに発生しました

出る時と出ない時の違い

実は今回は警告は初めは出ませんでした
あることをしたら出るようになったのですが、そのあることとは

Deployment Target を 9.3 から 8.0 に変更した

になります
これをやると警告が出るようになりました

対処方法

で、結局どうやって対応したかですが結論としては

  • 何もしていない

になります

警告文をよく調べてみると PIE ( Position Independent Executable ) が有効になっているせいで警告が出ているケースが主な原因であることが判明しました
その対応方法は公式にも出ていて

  1. In Xcode, select your target in the “Targets” section, then click the “Build Settings” tab to view its settings.
  2. For iOS apps, set iOS Deployment Target to iOS 4.3 or later. For Mac apps, set OS X Deployment Target to OS X 10.7 or later.
  3. Verify that Generate Position-Dependent Code is set at its default value of NO.
  4. Verify that Don’t Create Position Independent Executables is set at its default value of NO.

を設定するみたいです
しかし、自分の場合すべてクリアしているにも関わらず該当の警告が発生し続けました

更に調べてみると Cocoapods の以下の issue にたどり着きました

でここでは結局「Apple 側のバグでしょ、いづれ対応してくれるよ」という結論で Close されています ( 一応まだ別の場所で議論はされているみたいですが )

ここで自分も気づいたのですが、確かに警告をみると自分のプロジェクトが PIE として怒られているわけではなく Cocoapods でインストールしらライブラリが警告の対象になっていることがわかりました
なので、自分のアプリは PIE の対象外だと判断してそのまま iTunes Connect で審査に提出しました

結果的には

審査は問題なく通過しました
ということで今回と同じケースに遭遇した方は基本何もしないで OK です
ただ、自分のアプリの PIE 自体は対応しなければいけない問題なので、自分のアプリで PIE が有効になっている場合は Build Settings を No に変更してビルドし直してください

2017年2月20日月曜日

Xcode で iOS アプリを作る際に抑えておきたい技術

概要

個人的にアプリを作っていて「この技術やツール、仕組みは知っておいて損はない」という項目を集めてみました
細かい使い方は説明しませんがキーワードを元に自分で調べてみるといいと思います

環境

  • Mac OS X 10.11.5
  • Xcode 7.3.1
  • Swift 2.2

ツール

Cocoapods

ライブラリを管理するためのツールです
Ruby で書かれているため Gem コマンドを使ってインストールします
Podfile という設定ファイルにインストールしたいライブラリを記載することで簡単にライブラリを追加することができます
昔は zip ファイルを落としてプロジェクトに追加してみたいな面倒なことをやっていたのですが、これを使えばそんなことをしなくて良くなります
同じようなツールで Carthage というものがあります

Swift

最近は専ら Swift で書かれているアプリが多いと思います
Swift が出る前は Objective-c (Objc) でしたが Objc よりも遥かにコーディングしやすいです
コーディングのしやすさもありますが、コードの読みやすさやシンプルに書ける (コードの量が減る) 等のメリットもあると思います
最近では Web 上にもいろいろとノウハウが溜まってきたので導入の障壁も下がったのではないかと思います
ただ、まだまだ開発は進んでおり今後も文法の変更や新機能の追加等があるので、Swift がバージョンアップしてコンパイルが通らなくなる可能性があるという点は考慮しておく必要がありそうです

技術

IBOutlet

Storyboard で作成した UI コンポーネントをコード上 (.swift ファイル等) で扱えるようにするための技術です
Storyboard 上で作成したコンポーネントは基本的に Storyboard だけで設定 (色やフォントサイズなどの設定) をしたほうが良いのですが、例えば動的に変更したいケースがあると思います
そういう場合は IBOutlet を使ってコンポーネントとコードをひも付けてコード上で動的に変更するような処理を実装する感じです

IBOutlet 自体の作成も非常に簡単で Storyboard 上からコードに対してドラッグアンドドロップで紐付けるだけです

IBAction

同じく Storyboard 上で作成したコンポーネントを支援するための技術です
IBAction は主にボタンやタップ等のイベントをコンポーネントに紐付けるためのもので、IBOutlet 同様に Storyboard からコード上にドラッグアンドドロップするだけで作成することができます

例えばボタンが押されたときに、この IBAction を実行するみたいなひも付けが簡単にできます

Segue

ある UIView から別の UIView に移動するために使う技術です
UIView と UIView を Segue でつなぎその Segue に名前を付けます
指定された名前の Segue をコード上で呼び出す (performSegueWithIdentifier -> prepareForSegue) と次の UIView に移動することができます

設定も IBOutlet や IBAction と同じように設定できますが Segue の場合は移動する際のアニメーション (show や modal など) 指定することができます

Constraints (Autolayout)

これが使えるか使えないかで、アプリのレイアウトが大きく変わると思います
具体的に言うと Autolayout が使えると iPhone5s でも iPhone6 でも iPad でもレイアウト崩れを起こさず表示することできるようになります

設定 (操作) がやや面倒なのがネックかなと思います
コード上でも Autolayout を使ってレイアウトを設定することができますが個人的には Storyboard 上で設定するほうが簡単です
Storyboard 上で設定すれば実際にどういうレイアウトになるかプレビューを見ながら確認することができます
ただ、複雑な Constraints を設定しすぎるとプレビュー機能が全く機能しなくなるケースがあったので、その場合は実機やシミュレータで確認する必要があります

Delegate

よく使うのは UITableViewDelegate かなと思います
例えばセルを選択したときに didSelectRowAtIndexPath が呼ばれるようにするとかピッカーの値が選択されたときに didSelectRow が自動的に呼ばれるようすることができます

基本的には ViewController に必要な Delegate を継承し必要なメソッドを実装することで呼ばれるようになります

呼ばれない場合はうまく Delegate が UI コンポーネントに紐付いていないケースが多いです
ひも付けはコード上でも Storyboard 上でも可能です

最後に

上記を記載した理由というか背景ですが、個人的には

  • これだけあればある程度のアプリが簡単に作れる

という観点で記載しました
なので、他にも抑えておきたい技術やツールはたくさんあると思います

特にゲーム系のアプリをつくる場合は Sprite Kit など使えないと厳しいと思います

2017年2月19日日曜日

The certificate used to sign “appname" has either expired or has been revoked. An updated certificate is required to sign and install the application.

概要

実機でテストするときや iTunes Connect にアップロードするに出る証明書エラーです
自分なりにまとめた解決手順を紹介します

環境

  • Mac OS X 10.11.5
  • Xcode 7.3.1

原因・背景

同じアプリを 2 台の Mac で開発していて証明書や Provisioning Profile が PC 間で異なっているためタイトルのエラーが発生しています
開発している PC に証明書をインストールし直すことで解決することができます

対処手順

Certificates, Identifiers & Profiles (Developer Center) での作業

DeveloperCenter にログインして、以下の 3 項目を削除します

  • Certificates から iOS Development を削除する
  • Identifiers の App IDs から XC Wildcard のアプリ ID を削除する
  • Provisioning Profiles から iOS Team Provisioning Profile: * を削除する

上記はもう 1 台の Mac から作成されたものを想定しています
削除後に使用中の Xcode から再度作成を行います

Xcode で証明書を作成する

Xcode で

Targets -> General -> Team

に「Fix issue」の警告が出ているはずなのでボタンを押して修正します
すると DeveloperCenter に自動で Certificates から APP ID, Provisioning Profile を作成してくれます
そして、DeveloperCenter にアップロードした証明書と同じ証明書を現在使用している Mac にインストールしてくれます
キーチェーンアクセスで証明書を調べると生成した証明書がインストールされていることが確認できると思います

クリーンしてビルド

実機を接続して Xcode ビルドしましょう
ビルドの前に一度クリーンしないとエラーが継続することがあるのでクリーンしてください

最後に

たぶんこの手順で別の Mac でも実機テストできるようになると思います

再生成はしますが一度、証明書、AppID、Provisioning Profile が DeveloperCenter からなくなるので APNS など使っている場合は PushNotification 用の証明書を再度準備する必要が出てくると思います

なので、できれば証明書を配布して開発したい各 Mac にインストールしてこの問題を解決するか開発中のアプリなどでやるようにしてください
リリース中のアプリの証明書などが DeveloperCenter からなくなったときの具体的な挙動がわからないので、、、