学生かえるエンジニアのブログ

iOSを主にやる勉強中エンジニア。かえるが好き。ピクルスってかわいいよね。

IPA ファイルを作成して DeployGate へアップロードまでを自動で on TravisCI

個人制作のアプリで、github に push したら、TravisCI で ipa ファイルを作成して DeployGate にアップロードするまでの流れを自動で行うようにしました。

わりと手こずったりしたので、備忘のためにも記事にしておきます。

前提

  • p12 ファイルなどを扱うので全て自己責任で注意して行ってください。
  • 今回は ipa 作成 〜 deploygate へアップロード の流れにフォーカスしているので、その他の詳しい説明 (プロファイルの作成方法、DeployGate・TravisCIの使用方法等) は割愛します。

バージョンや状況

Xcode CI
9.3 TravisCI
  • 記事執筆日時: 2018/04/22
  • Manual signing を使用しています
  • CocoapodsCarthage も使っています
  • 今回自分が試したプロジェクトには TodayExtensionwatchOS系 の target が含まれています

.travis.yml ファイル

細かな手順などは後に書いてます。
便宜上最低限の記述のみにしています。

language: objective-c
osx_image: xcode9.3

script:
  # keychain
  - sudo security import <証明書>.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign
  - sudo security import <証明書>.p12 -k /Library/Keychains/System.keychain -P <PASSWORD> -T /usr/bin/codesign

  # provisioning profile
  - mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
  - mv <PPFILE_PATH> ~/Library/MobileDevice/Provisioning\ Profiles

  # xcodebuild
  - xcodebuild -workspace <PROJECTNAME>.xcworkspace -scheme <SCHEME_NAME> -configuration <Release> archive -archivePath <ARCHIVE_PATH>
  - xcodebuild -exportArchive -archivePath <ARCHIVE_PATH>.xcarchive -exportPath ./build -exportOptionsPlist <PLIST_PATH>.plist

  # deploygate
  - curl -f -F "token=<API_KEY>" -F "file=@build/<IPA_FILE>.ipa" https://deploygate.com/api/users/<OWNER>/apps

手順

1. cer, p12 ファイルの用意

既に用意できてる場合は大丈夫です。ない場合は下記の3つの手段のいずれかで用意してください。
p12 ファイルを書き出す際にはパスワードを設定しますので、忘れないようにしてください。

用意したファイルを git 管理下に移動してください。

  • Mac の キーチェーンアクセス から書き出す (for cer & p12)

キーチェーンアクセス.app を開いて、該当の証明書を右クリックし、cerとp12ファイルを書き出します。

  • Xcode から書き出す (for p12)

Preferences > Accounts > 該当のアカウント > ManageCertificates > 該当の証明書を右クリック > Export Certificate

  • Apple の Developer サイトからダウンロード (for cer)

こちら にアクセスし、該当の cer ファイルをダウンロードしてください。

コマンドの説明

TravisCI で下記を実行しています。
<証明書><PASSWORD> は書き換えてください。

sudo security import <証明書>.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign
sudo security import <証明書>.p12 -k /Library/Keychains/System.keychain -P <PASSWORD> -T /usr/bin/codesign

ログの24行目あたりに下記のように記されています。
本来WWDRCA証明書が必要なのですが、TravisCI上の macOS の Keychain には既に登録されています。 なのでこの Keychain を使用しています。

Fix WWDRCA Certificate
Unable to delete certificate matching "<省略>"security: AppleWWDRCA.cer: already in /Library/Keychains/System.keychain

2. ProvisioningProfile を用意

Xcode の signing 設定に指定している Provisioning Profile を用意します。
拡張子は.mobileprovisionです。
複数の target を用いているプロジェクトではその数分 Provisiong Profile も必要です。
既に用意できてる場合は大丈夫ですが、ない場合下記の2つの手段から用意してください。

用意したファイルは git 管理下に移動して下さい。

  • Apple の Developer サイトからダウンロード

ProvisioningProfile はここで作成します。既に作られている場合はダウンロードしてください。

  • Xcode の管理場所から持ち出す

Xcodeでは ~/Library/MobileDevice/Provisioning Profiles の場所で全て管理されています。
この中から該当のファイルをコピーして下さい。

コマンドの説明

-p オプションを付けて ProvisioningProfile を置くべきディレクトリを用意し、ファイルをそこまで移動しましょう。

mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
mv <PPFILE_PATH> ~/Library/MobileDevice/Provisioning\ Profiles

3. xcodebuild で ipa 作成

1行目で archive を作成し、2行目で ipa を作成します。
<> 内はご自分のものに書き換えてください。

xcodebuild -workspace <PROJECTNAME>.xcworkspace -scheme <SCHEME_NAME> -configuration <Release> archive -archivePath <ARCHIVE_PATH>
xcodebuild -exportArchive -archivePath <ARCHIVE_PATH>.xcarchive -exportPath ./build -exportOptionsPlist <PLIST_PATH>.plist

archive 作成

archive 作成コマンドを実行すると拡張子 .xcarchive のファイルが作成されます。
今回私のプロジェクトではcocoapodsを使用していたので workspace オプションで行っていますが、各自でコマンドは調整してください。
<ARCHIVE_PATH> は拡張子を含めず書きます。

ipa 書き出し

ipa ファイル作成時には、オプションを記述した plist ファイルが必要です。
下記に最低限を示しておきますが、詳しくは こちら が参考になります。
Xcode 上で管理すれば編集しやすいと思います。

作成した plist ファイルの場所を <PLIST_PATH> に記述しましょう。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>ad-hoc</string>
    <key>compileBitcode</key>
    <false/>
    <key>provisioningProfiles</key>
    <dict>
        <key>BUNDLE ID をここに</key>
        <string>Provisioning Profile の名前をここに</string>
    </dict>
</dict>
</plist>

4. DeployGate へアップロード

DeployGate の プロフィールページ の下部に API Key があります。
<OWNER> は あなたのユーザ名です。

公式ドキュメント を参考にして下さい。

curl -f -F "token=<API_KEY>" -F "file=@build/<IPA_FILE>.ipa" https://deploygate.com/api/users/<OWNER>/apps

補足

証明書などの扱い

.p12cer などの扱いは各自で注意してください。
特に.p12秘密鍵を含んでいるので注意してください。

TravisCI でのファイルの暗号化は 公式の説明 を参考にしてください。

パスワードの扱い

パスワードや API Key を .travis.yml にべた書きするのは避けるべきです。

https://travis-ci.com/<UserName>/<ProjectName>/settingsEnvironment Variables を使用する、travis encrypt コマンドを利用する、などなんらか別の安全な方法で行うべきです。

ライブラリ管理

carthagecocoapods を使用している場合は当然ながら install コマンド等を .travis.yml に書いてください。
キャッシュの設定などもするといいと思います。

その他

  • 私は xcpretty を使用していますが今回は省略して記述しています。
  • 当然 Provisioning Profile には実行したい端末の UDID が含まれてないといけません。

参考

後記

人によって環境が結構異なるでしょうし、詳しくなければ xcodebuild の認証周りで手こずる可能性が高いなど、一筋縄ではいかないことが多いと思います。
他のサイトなども参考にしながら、沢山試行錯誤しながら、頑張ってください。

間違いや感想、質問等、お気軽コメントどうぞ!

PDFKit で https が表示できない

Macには以前からあったようですが、iOSではiOS11から PDFKit が追加されました。

PDFKit の細かな話は自分で調べてもらうとして、今回は https://... のPDFが表示されず、対応策がネット上に英語の情報しか見つからなかったので書いておきます。

前提

Xcode Swift iOS
9.3 4.1 11.3

コード (結論)

let url = URL(string: "https://www.apple.com/business/docs/iOS_Security_Guide.pdf")!
let data = try! Data(contentsOf: url)
pdfView.document = PDFDocument(data: data)

注意

  • 便宜上 force unwrap してますが良くないので適宜修正して下さい
  • pdfViewPDFViewインスタンス

原因

PDFDocument のイニシャライズ時は通常 PDFDocument.init?(url:) を使うと思いますが、この時 https:// のurlの場合nilが返されます。

PDFDocument(url: URL(string: "http://...")!)  // PDFDocument instance returned
PDFDocument(url: URL(string: "https://...")!) // nil returned

さらに PDFViewdocument プロパティが PDFDocument? というようにnilを許容しているので、なにも表示されない原因に気付きにくいです。

// nothing happens
pdfView.document = PDFDocument(url: URL(string: "https://...")!)

詳しい事などは 参考 を参考にしてください。

参考

後記

もっと英語できるようになりたい(ってかれこれ6年くらいいってる)

Chromeのユーザー画像変更

Chrome を愛用してます。
複数ユーザーの機能があるので他のブラウザには乗り換えれません。

各ユーザのアバター画像が意外とすんなり変更できなかったので、書き残しておきます。

f:id:yuki0n0:20180320133118p:plain

前提

macOS Chrome
HighSierra 10.13.3 65.0.3325.162

手順 ~ ChromeGoogleアカウントでログインしてる編 ~

ChromeGoogleアカウント を紐付けてブックマークやパスワードの同期機能使ってる人向け。

1. Googleアカウント にプロフィール画像設定

https://aboutme.google.com/ にアクセスして、プロフィール画像を設定しましょう。

2. Chromeにログイン

chrome://settings すでに Chrome にログインしているなら、一度ログアウトして、再度ユーザを追加してログインします。

3. プロフィール画像を消す

手順1で設定したプロフィール画像はあなたの Googleアカウント での公開情報となってしまいます。 今回は Chrome 上のアバター画像を変更したいだけですので、 Googleアカウント から画像を削除します。

https://get.google.com/albumarchive/ ここから先程アップロードした画像のページに行き、削除してください。

そのままでいい人はそのままで、以前別のプロフィール画像を使っていた人はもう一度手順1で設定しなおします。

手順 ~ ChromeGoogleアカウントでログインしてない編 ~

1. 画像用意

アイコンにしたい画像を用意しましょう。正方形の PNG がいいと思います。

ファイル名は Google Profile Picture.png としておきます。

2. 画像を移動

Google Profile Picture.png~/Library/Application Support/Google/Chrome/Default の中に移動してください。

ユーザーのフォルダについて

パスの Default は変更したいユーザのフォルダに置き換えてください。

Chrome の各ユーザーの設定情報などは Default Profile 1 Profile 2 ... というフォルダに格納されています。

※ 自分が設定した名前のフォルダ名にはなっていません。

3. Local State ファイルを編集

~/Library/Application Support/Google/Chrome/Local State 場所はこちら。
拡張子はありませんがただの json ファイルです。

この json"profile" > "info_cache" > "Default" に下記を追記/変更してください。

"gaia_picture_file_name": "Google Profile Picture.png"
"use_gaia_picture": true

編集時の注意

  • 編集前に Chrome は終了しておきましょう。
  • json の要素 Default は先述したように自分が変更したいユーザーに置き換えてください。
  • Local State ファイルのjsonは改行されていない1行のファイルなので適宜うまいことしてください。

完了

下記のようなユーザ選択画面で画像を変更できたら成功です。

f:id:yuki0n0:20180320133148p:plain:w200  f:id:yuki0n0:20180320133152p:plain:w200
f:id:yuki0n0:20180320133855p:plain

補足

  • Windows でできるかわかりませんが、同じことをやるとしたらパスが違うようです。あっているかわかりませんがここっぽいです。~/AppData/Local/Google/Chrome/User Data/

参考

後記

なんか別にこんな記事よりもっと書きたいことあるのに...

モチベーションと時間の問題。

Qiita にも書いてみた。

xcodebuild でビルドだけする on CI

TravisCI で xcodebuild 実行してビルド通過するかチェックしたいなと思いました。

個人開発のアプリなのでユニットテストなども書いて無く、とりあえずビルドをパスするかどうかだけチェックしたかったんですが、意外と引っかかってしまったのでメモしておきます。

前提

  • テストを書いてない
  • 今回はただビルドするだけ
  • Targets に Today ExtensionWatchKit App がある
  • CocoapodsCarthage を使用

結論

下記のようなコマンドを実行

xcodebuild -workspace Sample.xcworkspace \
-scheme Sample \
-destination 'name=iPhone 8' \
build

つまずきポイント

-destination ではなく -sdk オプションを指定していた

これのせいで、Today Extension の build でつまづいたり、Provisioning Profile を用意しろと言われたり、auto signing / manual signing が原因かと思い試行錯誤したりしていました。

補足

この記事での目的は xcodebuild の話だったので趣旨には沿いませんが、私が TravisCI 上で何をしていたのかなど含め簡単に書いておきます。

.travis.yml にどのように書いたかなどは割愛させて頂きます。

CocoaPods / Carthage

もちろん pod install carthage bootstrap など実行します。そうしないとビルドが通りません。

時間

Carthage のライブラリインストールは比較的時間がかかるため、travis_waitを活用すると良いと思います。

キャッシュ

ディレクトリの Carthage/Pods/キャッシュすべきでしょう。

xcpretty

xcpretty を使って xcodebuild のログを見やすくしました。 大したことはしてませんがまたいずれ記事にできたら良いかなと思います。

GitHub - supermarin/xcpretty: Flexible and fast xcodebuild formatter

参考

xcode7 - How to use xcodebuild in Xcode 7 with a watch extension - Stack Overflow

Xcodeでのビルドを自動化するxcodebuildコマンドとIPAファイルを作成してiTunes Connect(Testflight)に投げる方法 - 酢ろぐ!

後記

github に push したら、そのまま TestFlight / DeployGate などにデプロイしたり、fastlane 使ったりしてアプリ申請まで自動で行ったり、どんどん自動化していきたい。

けど個人開発のちょっとしたアプリでそこまで労力かけるのもね。

TravisCI を使用して GAE にデプロイ

最近GCP*1のGAE*2を使用しています。github上で特定のブランチが更新されたら自動でデプロイしてほしいなと思い、Travis CI で自動デプロイされるよう試みました。

※ 今回テストなどは走らせていません。ただただデプロイするだけです。

.travis.ymldeploy キーを利用したデプロイプロバイダを使用した方法がありますが、今回は利用していません。

※ サービスアカウントキーを扱うなど、セキュリティ面での懸念点があります。当記事は全て自己責任でご参考下さい。

手順 (目次)

  1. The Travis Client をインストール
  2. サービスアカウントキー作成
  3. サービスアカウントキー暗号化
  4. .travis.yml 編集
  5. リモートリポジトリへプッシュ

方法

1. The Travis Client をインストール

travis コマンドを使用できるように、The Travis Client をインストールします。

gem install travis

詳しくは公式ページを参考にインストールして下さい。

2. サービスアカウントキー作成

GCPAPIとサービス/認証情報ページに行き、サービスアカウントキーを作成して下さい。作成する際はJSONを指定しましょう。

作成後にダウンロードされたjsonファイル名を今回は client-secret.json とします。

f:id:yuki0n0:20171012040213p:plain:w300
f:id:yuki0n0:20171012040220p:plain:w300

3. サービスアカウントキー暗号化

travis コマンドを利用し、ファイルを暗号化します。

travis login --pro
travis encrypt-file client-secret.json --add

--add オプションをつけることで .travis.yml にファイルを復号化するコマンドを自動で追記してくれます

4. .travis.yml 編集

下記は最低限の.travis.ymlを示しています。

language: ruby

env:
  - PATH=$PATH:$HOME/google-cloud-sdk/bin

before_install:
  - openssl aes-256-cbc -K $encrypted_key -iv $encrypted_iv
    -in client-secret.json.enc -out client-secret.json
    -d

install:
  # install gcloud
  - export CLOUDSDK_CORE_DISABLE_PROMPTS=1
  - curl https://sdk.cloud.google.com | bash

  # setup
  - gcloud config set project <projectid>
  - gcloud auth activate-service-account --key-file client-secret.json

script:
  - gcloud app deploy

まずbefore_installで暗号化したjsonファイルを復号化します。これらは手順3で自動追記されたものです。

そしてinstall内でgcloudコマンドをインストールし、deploy出来るようにprojectidやアカウント情報などを読み込みます。

今回の方法で google cloud sdk をインストールした場合。google-cloud-sdk/bin/gcloud にgcloudがあります。そのためenvでパスを通します。

最後に script でデプロイしています。

5. リモートリポジトリへプッシュ

.travis.ymlclient-secret.json.enc を add/commit し、push しましょう。

client-secret.jsongit add/commit/pushしないで下さい。

備考/補足

  • 現状だと毎回gcloudをdownload/installしてるので、TravisCI上のcacheなどを利用すると良いと思います。

  • deploy時のオプションなどお好みでセットしましょう。

  • client-secret.json はgit管理下で保持しておくならば.gitignoreに含めておきましょう。

  • 上記に示した .travis.yml は最低限のものです。 branchesafter_success など各自で記述して下さい。

参考

後記

CIとかもっと活用していけたらいいな。

間違いとかアドバイスとかあればコメント下さい!

*1:Google Cloud Platform

*2:Google App Engine

Xcode9 & iOS11 で ワイヤレスデバッグ

Xcode9iOS11 を使用するとワイヤレスで実機テストができるようになりました!

かなり便利!

方法

1 Devices を開く

Xcode のメニューバーから Window > Devices and Simulators を開く

f:id:yuki0n0:20170927194529p:plain

2 Connect via network を ON

最初は実機とUSBで接続して下さい。

f:id:yuki0n0:20170927195926p:plain

3 実機で実行

右側に地球のマークがでます。

(当然MaciPhoneを同じネットワークに接続して下さい。)

f:id:yuki0n0:20170927200245p:plain

参考

後記

大学の後期がはじまって1週間くらいたちました。疲れた。

localhost:8000 とかを公開、共有

はじまり

webページの開発・デバッグ時はlocalhostの任意のポートで確認すると思いますが、この開発中のページを一時的に公開したり、外部から接続したくなることがでてきました。

そしてそういうサービスが存在することを知ったため、この類のサービスをいくつか試し、無料で使用できる2点を紹介します。

筆者はweb開発などに対し知識が浅いです。今回紹介することは、通常外部からアクセスできないlocalhostに対して穴を開けてアクセスできるようにすることなので、セキュリティ上のリスクは少なからず高まります。ご利用される際は自己責任でお願いいたいます。

ngrok

https://ngrok.com/

結構有名でよく使用されてるっぽいです。

インストール

公式ページからOSにあったngrok.zipをダウンロード、解凍したら使用できます。

直接ngrokが存在するディレクトリに対して./ngrok としてもいいし、pathの通ってる所に解凍したngrokを移動してもいいと思います。

使用方法

8000ポートを解放

$ ngrok http 8000

ベーシック認証をつける

$ ngrok http -auth "user:password" 8000

ポイント

localtunnel

https://localtunnel.github.io/www/

ngrokよりは使用されてない感じがしますが、ソースコードが公開されており、全て無料で利用できます。

インストール

nodejs が必要です

$ npm install -g localtunnel

使用方法

8000ポートを解放

$ lt --port 8000

サブドメインを指定

$ lt --port 8000 --subdomain aiueo

ポイント

類似サービス

今回紹介しなかったけど、他にも色々あるみたいです。

参考

後記

Apple界隈では、iOS11やらiPhone8、iPhoneXやら、賑わってますね。

最近はwebやapiを見ることが多いです。