20191009のiOSに関する記事は10件です。

Nature Remoで室温を取得して場合に応じてエアコンをつけるショートカット

概要

これまでITFFFとNatureRemoを組み合わせて使っていましたが、ふとiOSのショートカットを組み合わせると楽しそうと思い立ちました。
(例えば、朝のアラームを止めたら部屋の明かりがつくみたいな)

今回は比較的面倒な室温が高かったら自動で冷房をつけるというショートカットを紹介します。
ちなみに、オートメーションで最寄り駅に到着した時などに実行するというイメージです。

手順

では具体的に説明していきます。

NatureRemo APIの取得

NatureRemoのサイトに飛んでして、アクセストークンを取得してください。

他でも紹介されてるのでNatureRemoのことは他を参照してください。
NatureRemoAPIを使用してRESTで家電を操作する
Nature Remoの公式APIの使い方

ショートカットでAPIを叩く

まず先ほど取得したアクセストークンをオーソライズのスキームと一緒にテキストに書いて、変数として保持しておきます。
Bearer [access token]
20191009_130543000_iOS.jpg

次にAPIのurlを指定して、内容を取得し、変数にしておきます。
20191009_131043000_iOS.jpg
方法のGET、ヘッダのAuthorizationも忘れずに

ちなみにmyJSONの中身は
20191009_132025000_iOS.png
こんな感じです。

辞書で必要なデータだけ取り出し、整える

今回は室温を取得するのが目的なのでデータを適宜抽出します。
20191009_130622000_iOS.jpg
(これらのキーは上のJSONの中身と対応してます、当然ですが)

最後の計算のところは、これからifの処理に入るために行っています。
イメージはjavaなら下記のコードに当たるような処理です。
double valueDouble = Double.parseDoube(valueStr);

任意の温度と比較して処理を実行

基準となる温度を決め、if文で処理しましょう。
室温を変数として宣言していない場合も、マジック変数という便利機能で参照できます。
今回は30度で設定していますが、適当な数字を設定してください。
20191009_130704000_iOS.jpg

if文の主語が基準で比較対象に室温がくるのが気持ち悪いのですが、
先に室温をもってくるとなぜか大小を比較するオペレーターが選択できなくなります。
(とてもAppleらしいんですが条件式が完全に自由に組めるわけではないんです...)

ショートカットで使いたい処理が見つからない!

NatureRemo編

ショートカットはこれまで使ったことのある処理を候補として表示してくれます。
つまりフルにNatureRemoの操作を選択できるわけではありません。
一度アプリを開いて自動化したい処理を実行しましょう。

もともと実装されているもの

今回使っているものだけどこにあるか明記しておきます。
書類
テキスト
スクリプティン
辞書の値を取得
数字
数値をフォーマット
if文
変数を設定
Web
URL
URLの内容を取得

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AVFoundationを使った動画編集(再生速度を変える)

AVFoundationを使った動画編集(簡単なフェード処理)の続きで、映像の再生速度を変更して早送りにしたりスローモーションにしたりしてみます。

出力用のCompositionとTrackの準備

let srcAsset = AVURLAsset(url: url1)

let composition = AVMutableComposition()

// 出力用VideoTrackを作る
guard
    let videoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) else {
    debugPrint("Failed to add video tracks")
    return
}

CompositionとTrackの準備については、前回の内容と同じです。

再生速度を指定して映像を追加するメソッドを作る

private func copyVideoTrack(of asset: AVAsset,
                            start: TimeInterval,
                            end: TimeInterval,
                            to track: AVMutableCompositionTrack,
                            duration: TimeInterval,
                            at: TimeInterval) throws {
    let srcVideoTrack = asset.tracks(withMediaType: .video)[0]
    let timeScale = srcVideoTrack.naturalTimeScale

    // 元の映像の切り出す範囲
    let srcTimeRange = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: timeScale), end: CMTime(seconds: end, preferredTimescale: timeScale))

    // 出力先トラックでの挿入位置(再生開始時刻)
    let insertAt = CMTime(seconds: at, preferredTimescale: timeScale)

    // 一旦そのままの長さで挿入する
    try track.insertTimeRange(srcTimeRange, of: srcVideoTrack, at: insertAt)

    // 再生時間(再生速度)を変更する
    track.scaleTimeRange(CMTimeRange(start: insertAt, duration: srcTimeRange.duration), toDuration: CMTime(seconds: duration, preferredTimescale: timeScale))
}

元の映像から、出力用の映像トラックに映像を貼り付けるメソッドを用意します。

元映像の再生速度と貼り付け先の再生速度が変わる関係で若干ややこしいので細かくみていきます。

let srcTimeRange = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: timeScale), end: CMTime(seconds: end, preferredTimescale: timeScale))

まず、元の映像から切り出す範囲を決定します。startendという二つの引数で開始時刻、終了時刻を秒で指定します。timescaleは元映像のtimescaleで統一します。

let insertAt = CMTime(seconds: at, preferredTimescale: timeScale)

次に、出力先トラックの挿入位置を決定します。

try track.insertTimeRange(srcTimeRange, of: srcVideoTrack, at: insertAt)

切り出す範囲と挿入位置が決まったら、一度元のスケール(再生速度)のままトラックに映像を挿入します。

track.scaleTimeRange(CMTimeRange(start: insertAt, duration: srcTimeRange.duration), toDuration: CMTime(seconds: duration, preferredTimescale: timeScale))

その後、scaleTimeRangeメソッドを使って挿入した箇所のスケール(再生速度)を変更します。

最初の引数(CMTimeRange(start: insertAt, duration: srcTimeRange.duration))は、出力用トラックにおける再生範囲です。元映像における再生範囲ではないので注意しましょう。ここでは映像を挿入した位置(insertAt)から元映像における切り出し範囲の長さ(srcTimeRange.duration)分を再生速度変更の対象として指定します。

次の引数(toDuration: CMTime(seconds: duration, preferredTimescale: timeScale))では、対象となる範囲を何秒に圧縮/引き延ばすかを指定します。ここでは、durationという引数で指定した秒数になるように指定しています。もし元映像から再生速度の倍率で指定したい場合はCMTimeMultiplyByFloat64(_:multiplier:)などを使って、元の映像の長さから計算しても良いと思います。

Trackに映像を切り貼りしていく

// それぞれのトラックから最初の5秒を取り出す
do {
    try copyVideoTrack(of: srcAsset, start: 0.0, end: 1.0, to: videoTrack, duration: 1, at: 0.0)
    try copyVideoTrack(of: srcAsset, start: 1.0, end: 14.0, to: videoTrack, duration: 1.0, at: 1.0)
    try copyVideoTrack(of: srcAsset, start: 14.0, end: 15.0, to: videoTrack, duration: 1.0, at: 2.0)
} catch let error {
    debugPrint(error)
    return
}

上で用意したメソッドを使って、元映像から出力用トラックに映像を切り貼りしていきます。上のコードでは、

  1. 元映像の最初の1秒を等倍速で貼り付け
  2. 元映像の1秒〜14秒までの13秒間を1秒間に圧縮して貼り付け
  3. 元映像の14秒〜15秒までの1秒間を等倍速で貼り付け

という形で、再生速度を変えながら元映像の15秒分を3秒に圧縮して追加しています。

Instructionの設定とプレビュー

// 出力用のビデオトラックに対するlayerInstruction(今回は何もしない)
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)

// VideoCompositionに対するinstruction
let instruction = AVMutableVideoCompositionInstruction()
instruction.layerInstructions = [layerInstruction]

// instructionはビデオトラック全体に適用されるようにする
instruction.timeRange = videoTrack.timeRange

// VideoComposition
let videoComposition = AVMutableVideoComposition()
videoComposition.frameDuration = CMTime(value: 1, timescale: 30)
videoComposition.renderSize = videoTrack.naturalSize
videoComposition.instructions = [instruction]

let playerItem = AVPlayerItem(asset: composition)
playerItem.videoComposition = videoComposition

let player = AVPlayer(playerItem: playerItem)
playerView.player = player

InstructionやAVPlayerを使ったプレビューについては、AVFoundationを使った動画編集(簡単なフェード処理)と同じなので説明を省略します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOS13 復活したpopoverLayoutMarginsをおさらい

概要

前々から使いたかったのに全然思う通りに動いてくれなかったUIPopoverPresentationControllerpopoverLayoutMarginsがiOS13で動くようになっていました!
むしろ動くようになったことでレイアウトが崩れていましたが←
やっと役割を果たしてくれるということで、機能と使用方法のおさらいを簡単にまとめていきます。

popoverLayoutMarginsとは

PopoverのUIViewControllerを設定する際などに使うUIPopoverPresentationControllerの配置に関わるプロパティです。
普通にPopoverを表示するとNavigationBarに被ってしまったりして困る時がありますね。

deactive_margin.png

MarginとあるようにPopoverを表示する際に画面からのマージンを設定することで
NavigationBarに被らないようにできるはずなのですが、、
iOS8以降設定しても表示に全く変化がありませんでした。。

iOS 8 popoverpresentationcontroller popoverlayoutmargin not working - Stack Overflow

これはApple側のバグとしてレポートが提出されていましたが、iOS12になっても全然修正されず(汗
てっきりもう無くなるものだと思っていましたが!!ここへ来てまさかの復活!!笑
iOS13の動作確認中にレイアウトが崩れていたので、半信半疑使ってみて復活に気づきました。
嬉しいような悲しいような?苦笑

使用方法

環境

  • iOS 13.0
  • Xcode 11.0
  • Swift5

コード

と言ってもかなり簡単です。
設定したいマージン値のUIEdgeInsetsをSetするだけです。

Popoverを開きたい親のUIViewControllerか、PopoverであるUIViewControllerのどちらか一方に処理を書けばいいです。
今回は親側に実装してみます。

SampleViewController.swift
import UIKit

class SampleViewController: UIViewController
{
    /// Popoverを開く
    ///
    /// - Parameter sender: UIButton
    @IBAction func openPopover(_ sender: UIButton)
    {
        let popoverVC = PopoverViewController()
        popoverVC.preferredContentSize = CGSize(width: 230, height: 200)
        popoverVC.modalPresentationStyle = .popover
        popoverVC.popoverPresentationController?.sourceView = sender
        popoverVC.popoverPresentationController?.sourceRect = sender.bounds
        popoverVC.popoverPresentationController?.permittedArrowDirections = .left
        popoverVC.popoverPresentationController?.delegate = self
        // CHECK: NavigationBarとButtonに被らないようにMarginを設定
        popoverVC.popoverPresentationController?.popoverLayoutMargins = UIEdgeInsets(top: 50, left: 10, bottom: 0, right: 0)
        present(popoverVC, animated: true, completion: nil)
    }
}

extension ViewController: UIPopoverPresentationControllerDelegate
{
    // MARK: UIPopoverPresentationControllerDelegate

    /// adaptivePresentationStyle(iPhoneで表示させる場合にのみ必要)
    func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle
    {
        return .none
    }
}

margin_active.png

これでPopoverが他のパーツに被ることなく表示できますね!

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Xcode11.1にiOS12.4シミュレータが無い

Xcode11.1がリリースされたのでインストールしたのですが、Xcode10.3で使用していたiPhone XS - iOS12.4のシミュレータが無い。
シミュレータの設定画面から作成しようとしてiPhone XSを選びiOS12.4を選択しようとしたがiOS12自体が無く作成出来ない。
じゃあiOS12.4のシミュレータをダウンロードするかとダウンロード画面を開くとiOS12.2以下しか見当たらない。
困ったのでググってみるとXcode11では起きてる問題の模様。
以下のStack Overflowの回答通りXcode10.3のiOS.simruntimeファイルをコピー&リネームしXcode11.1内にiOS 12.4.simruntimeを配置したら問題なくXcode10.3で使用していたiPhone XS- iOS12.4などが表示されるようになりました。
Answer: iOS 12.4 is missing in Xcode 11 GM

Xcode10.3のiOS.simruntimeの場所
/Applications/Xcode10.3.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes

Xcode11.1のiOS 12.4.simruntimeを配置する場所 (Xcode10.3と同じ)
/Applications/Xcode11.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes

こんな感じで元のiOS.simruntimeとiOS 12.4.simruntimeが同じ場所にある状態になります。
runtimes.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

structのMemberwise Initilaizer(swiftが用意してくれてるinit)の挙動

structの生成ができない!と焦った経験があり、忘れないようにメモ程度で残します。

structのMemberwise Initilaizerについて

struct MyData {
    var name: String
}

上記のようなstructはinitを定義してなくても

let data = MyData(name: "hoge")

とMemberwise Initilaizerが存在します。

ただ場合によっては利用出来ないこともあります。

struct MyData {
    var name: String
    private var age: Int?
}

上記のようなstructがある場合、MyDataを生成することは不可能です。

ageがprivateになっているため、initを用意してくれてしまうとprivateとしての意味がなくなってしまうから。

だと思います。

struct MyData {
    var name: String
    private var age: Int?

    init(name: String, age: Int?) {
        self.name = name
        self.age = age
    }
}

そういうときにはinitを定義してあげるしかないですね。

privateな変数がある場合、initを定義せずにデータを生成する方法

privateな変数があるけどinitがないstructはたくさんのプロジェクトで使われてるはずです。

生成できないけど、どこで使われるのか。

import Foundation

struct MyData: Codable {
    var name: String
    private var age: Int?
}

jsonデータをdecodeするために、Codableを採用してる場合です。


ちなみにprivateな変数があるstructを生成しようとすると

error: 'MyData' initializer is inaccessible due to 'private' protection level

と怒られますが、
あまり経験したことがなく、
initも特に深く考えずに使ってることが多かったので焦りましたね。

initしてるだけだから、特にprivateの変数に外部からなにかしようとしてないんだけど!!なんで!?と思いハマっちゃいましたw

用意されるinitはinternalのものになるので、privateを勝手にinternalには変えてくれないということです。すごい当たり前の挙動ですねw

まあ考えてみれば当たり前のことなので、
お恥ずかしいですが、自分のような人はあまりいないと思いますが、メモとして残します!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOS fixed+慣性スクロールがなくなった?

背景

iPhoneでモーダルを表示するときなど、デフォルトで慣性スクロールしてくれないので-webkit-overflow-scrolling: touchを指定して、慣性スクロールを実現させているページがありました。
ですが、fixed+慣性スクロールの掛け合わせだと、動きが止まるときがあったので指定を外しました。
そしたらoverflow-scrollingの指定がないのにiPhoneでも慣性スクロールになっている?と思ったので、検証してみます。

検証用

See the Pen menu scroll test by かぶきち (@cubkich) on CodePen.

端末・バージョン別

iPhone7 iOS 13.1.2

私の持っている端末では、慣性スクロールが確認出来ました。

iPhone6 iOS 12.3.1

会社にある端末では、慣性スクロールの確認は出来ませんでした。

iPhone10s iOS ??.?.?

先輩の端末で見てみたら、慣性スクロールしていませんでした。

考察

もしかしたらiOS13からデフォで慣性スクロールしてくれるのかもしれない。
ただ、まだシェアがそこまで広がっていないと思うので、慣性スクロールできないことを前提に対応するべき。
かなぁ。

お使いのiPhoneでは慣性してますか?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOS デフォで慣性スクロールできるようになった?

背景

iPhoneでモーダルを表示するときなど、デフォルトで慣性スクロールしてくれないので-webkit-overflow-scrolling: touchを指定して、慣性スクロールを実現させているページがありました。
ですが、fixed+慣性スクロールの掛け合わせだと、動きが止まるときがあったので指定を外しました。
そしたらoverflow-scrollingの指定がないのにiPhoneでも慣性スクロールになっている?と思ったので、検証してみます。

検証用

See the Pen menu scroll test by かぶきち (@cubkich) on CodePen.

端末・バージョン別

iPhone7 iOS 13.1.2

私の持っている端末では、慣性スクロールが確認出来ました。

iPhone6 iOS 12.3.1

会社にある端末では、慣性スクロールの確認は出来ませんでした。

iPhone10s iOS ??.?.?

先輩の端末で見てみたら、慣性スクロールしていませんでした。

考察

もしかしたらiOS13からデフォで慣性スクロールしてくれるのかもしれない。
ただ、まだシェアがそこまで広がっていないと思うので、慣性スクロールできないことを前提に対応するべき。
かなぁ。

お使いのiPhoneでは慣性してますか?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Provisioning profile "XXXXXX" doesn't include signing certificate YYYY って出る場合の対処法(2019/10/9版)

うむ。
わかる。

きっと
「Provisioning profile doesn't include signing certificate」
あたりをググって来たんだろう?
すっげーイライラしてるんだろう?わかる、わかるぞ。
俺は1年前のお前だ。

きっとお前は1年前プロビジョニングでトラブったことなんて忘れてググったんだろう。
俺が1年後のお前に向けてやり方をメモっておくから参考にしてくれ。

1. キーチェーンアクセス設定

まずはいらない証明書を消そう

余計な証明書があるとどうやらまずいらしい。というわけで消す。「キーチェーンアクセス」を立ち上げて、Expired(期限切れ)している赤い☓マークの証明書を消そう。

スクリーンショット_2019-10-09_17_48_40.png

くれぐれも赤いバツマークがついているやつだ。何も無い期限内の証明書を消すんじゃないぞ。

2. Xcode 設定

Preference 設定

メニューから Xcode→Preferences を選んで以下の画面を出そう。画面の通り、Manage Certificates をクリック

スクリーンショット_2019-10-09_17_51_26.png

以下の画面の通りにApple Distribution を押そう。項目が追加されるはずだ。

スクリーンショット_2019-10-09_17_53_16.png

3. Apple Developer Portal 設定

Certificates を確認

https://developer.apple.com/account/resources/certificates/list
にアクセスして、サインインする。すると、さっき作ったのがあるはずだ。特に名前を設定していないので確認しようがないが、基本的には作った時間が一緒のはずだ。

スクリーンショット_2019-10-09_17_58_21.png

Profiles を追加

画面の通り、+を押してプロファイルを作っていく

スクリーンショット_2019-10-09_18_00_19.png

App Store を選んで、右のContinue ボタンをクリック

スクリーンショット_2019-10-09_18_00_44.png

きっと開発時では使ってたであろう、見慣れたApp ID を指定する。
右のContinue ボタンをクリック

スクリーンショット_2019-10-09_18_01_00.png

Certificates を指定する。 さっき Xcode で作ったやつしかないはず。もしこれが同じものが複数ある場合は混乱の元になるから見直そう。

スクリーンショット_2019-10-09_18_01_11.png

適当な名前(例: [アプリ名] Distribution (XXXXXXXX) )をつけて、右のGenerate ボタン

スクリーンショット_2019-10-09_18_01_26.png

4. 再起動

そう。一回、Macを再起動しよう。なぜか前のキャッシュが残っている場合がある。

5. Xcode でプロビジョニング設定

あとはお決まりのコースで、プロジェクトのSigning & Capabilities で
Bundle Identifier をいつものApp IDを入れ、
Provisioning Profile を先程作ったのを入れ、
Signing Certificate が先程作ったやつで、Apple Distribution になってればOK(iPhone Distribution とかなってない?)

スクリーンショット_2019-10-09_18_43_08.png

そして赤文字でエラー表示がなければビルドができるはず。Organizer使ってアップロードしよう。

以上!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Eurekaで可変的にRowを追加していく方法

自分のメモです

ここがとても参考になりました。
https://github.com/xmartlabs/Eureka/issues/519
皆さんも参考にしてみてください

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

エラーを100回以上出して学んだ CIツール(Bitrise) の使い方 【設定全公開】

はじめに

こんにちは! iOSエンジニアの やまたつ です☺️
Oshidori というアプリを個人で開発し、リリースしています!
この記事は仕事で得た知見を残すために書いております。
また、iOSエンジニアを目指す方のポートフォリオにCIツールを追加するときに読んでもらえたら良いな〜と思ってできるだけ丁寧に書いております。

何書いてるか

会社から「Slackからメッセージを送り、CIツールでビルドして DeployGate にアップロードして、結果を Slack に送る」というミッションをいただき、悪戦苦闘しながら知識を身に付け、なんとか形になりました?
この記事では、自分のアプリを元に上記の流れを再現していきたいと思います。(さすがに会社の設定は見せられないので笑)
この記事を書きながら Bitrise, DeployGate, Slack の設定をしていきます!

背景

以下のツイートに対して知り合いが「記事待ってます!」とリプしてくれたので記事化に踏み切りました笑

Bitrise 公式からも「記事待ってるよ!」的なコメントをいただき、さらに背中を押されました笑

Bitrise の概要

CIツールです。Jenkins や Circle CI などを聞いたことがある方は馴染みがあると思いますが、それの仲間みたいなもので、モバイル開発に特化しているCIツールです!
手順(Workflow)を用意しておいて、定期実行だったり、トリガー(Slackのコマンド、git で マージした時)によって実行させたりできる便利なやつですね!
AppStoreConnect にもアップできるし、DeployGate、TestFlight の配布ツールにもアップできます。

まずはこの記事で概要を掴みました。
【コード0行】BitriseでiOSアプリのデプロイ自動化してSlackに通知するまで

Bitrise への登録

登録してみましょう☺️
登録が終わったら、勝手にビルドされますが一旦放置で大丈夫です。
ここまでは楽勝✌️ ドキュメント見なくても行けます。
iOS用のCIサービスBitriseを使ってみた

証明書をアップロードしておく

ここをみたらアップロードできる!Code Signing に .p12 ファイルをアップロードしましょう!
iOS code signing - troubleshooting

DeployGate への登録

アカウント作成し終わったら、下の写真の「グループ」からアプリのページを新規作成します。
スクリーンショット 2019-10-08 午後8.02.24.png

そして、APIキーを控えておきます。
スクリーンショット 2019-10-08 午後8.02.49.png

Slack から実行する

この記事を読んだら登録できます! 自分の Slack 環境に専用チャンネル作って、登録してみましょう。
Slack上からBitriseのワークフローを実行する

ちなみに自分の設定はこちら↓↓↓↓↓
/bitrise_oshidori_ios のコマンドを入力すると bitriseコマンドを呼び出す設定にしてます!
スクリーンショット 2019-10-08 午後2.46.45.png

可愛い画像を登録して、コマンドの説明欄に以下のような記述をしておきます。
/bitrise_oshidori_ios b:master|w:deploygate
ブランチ指定とワークフロー指定をします!(bはブランチ、wはワークフローってこと)
ブランチは、Gitのブランチ名、ワークフローはBitriseで作ったワークフローの名前です!

スクリーンショット 2019-10-08 午後2.48.12.png

入力途中で予測変換みたいに出てきてくれて嬉しい?
スクリーンショット 2019-10-08 午後2.48.52.png

実際にコマンドを打つと、Bitriseと通信して、ビルドしてくれます。
今はエラーしか出ないと思いますが!!!実行してみることに価値がある。知らんけど?
/bitrise_oshidori_ios b:master|w:primary
/設定したコマンド b:ブランチ名|w:primary とすると、実行できると思います!(primary は最初からあるワークフローです)
スクリーンショット 2019-10-08 午後2.49.27.png

Bitrise のこれは知っとけ

ここからついに Bitrise を触っていきます?
触るのはほぼ Workflow なので軽く説明していきます。

以下の画像のような設定画面になっています。
スクリーンショット 2019-10-08 午後4.05.22.png

workflows

手順を並べるところ。一番触るところ。いろんな項目があるのでなんでもできそうと思っている。

Code Signing

証明書をおいておくとこ。 「~~.p12」ファイルとか
ここに証明書を置くから Bitriseがいろんなところにアップロードできるようになるんでしょうな。

Secrets

全体で使える環境変数。公開したくないものを書いておく。例えば APIキーや、AppleID, Password など。

Env Vars

全体で使える環境変数と、それぞれの workflow ごとに使う環境変数を設定できる。

Triggers

workflow を実行するトリガーを設定(今回はSlackからなので使用しません)

Stack

workflow を実行するパソコンのバージョンを選べる。Xcodeのバージョンも。
(iOS 13対応のSDK で出したいときは、 Xcode11 じゃないとダメなので設定を確認してください)

bitrise.yml

上記の設定を全て取りまとめて、yml で表示してる。ここをいじることはないであろう。。。(ymlファイルはいじり方を知りません?)

Workflows の設定

workflow は一つの workflow で完結させても良いのですが、いくつかの workflow を作成し、結合させた方が良いです。
再利用性が高まったり、保守がしやすくなります(オブジェクト指向と同じ匂いがします?)
参考:Bitrise のワークフローを分割して再利用性を高めよう

まずは実際に自分が作成した workflow をお見せします!
4つの workflow で構成した Oshidori_iOS_DeployGate です!

bitrise_oshidori_workflow.png

構成はこんな感じです↓↓↓↓↓↓↓

Chain_PrepareSetting
    ↓
Chain_SetupProject
    ↓
Chain_Archive
    ↓
Chain_Webhook

それぞれの workflow の説明

イメージとしては、新しいパソコンでデプロイまで持っていく感じです!
「新しいパソコンが手に入ったから、環境構築して、プロジェクトが動くようにして、アーカイブして、DeployGateにアップロードする」
という手順になってます!

実行した際にエラーはつきものですが、必ずエラーを読むようにしてください!!!?‍♂️
ログがきちんと表示されているので、読むだけでどこが悪いのか分かります!

Chain_PrepareSetting

環境構築の段階です!
この3つはお決まりとして覚えておくと良いでしょう。

ここで出るエラー

  • git clone ができてない
    • ブランチ名が間違っている可能性が高いです。slack で送っているブランチ名を見直しましょう

Chain_SetupProject

プロジェクトが動くように、pod install をしたり、GoogleService-Info.plist をダウンロードしています!
pods のバージョンを Podfile.lock に記載してあるバージョンに合わせましょう。
GoogleService-Info.plist は Git で管理したくないので、以下の記事を参考にしました。
CIサービスBitriseを使ったAdHoc配信のサンプル

詳細画像はこちら。
スクリーンショット 2019-10-08 午後8.09.06.png

(※企業で行った時はここに fastlane を使った環境構築や、 enterprise向けにプロジェクト構成を変更するスクリプトを書いたりしました。その時に必要だったことは、fastlaneの中で使うpasswordなどです。ここで死ぬほどエラーが出てました? 権限なかったり、path が合ってなかったり、pod のバージョンが合ってなかったり、要因はたくさんありましたね。。。)

ここで出るエラー

  • スクリプトがうまくいかない
    • ファイル階層が間違っていることがあります。スクリプト内に pwd を記述したりして階層を確認しましょう。
  • Pods のバージョンでのエラー
    • Podfile.lock の一番下に記述してあるバージョンと合わせましょう。

Chain_Archive

証明書の確認と、アーカイブをしています。
重要なのは、証明書と同じ TEAM_ID が設定されているかです!
$TEAM_ID という名前で、Secrets に設定しています。
証明書(Code Signing → CODE SIGNING IDENTITY → Team)の右に書いてある英数字です。

この辺↓↓↓↓↓↓
スクリーンショット 2019-10-08 午後7.44.59.png

ここで出るエラー

Chain_Webhook

DeployGate にアップロードして、終わったら Slack に流してます!
DeployGateに登録する の会で確保したAPIキーは Secrets に入れておきます。

これはOshidoriの設定画面です。参考にしてください。
DeployGate↓↓↓↓
スクリーンショット 2019-10-08 午後8.55.57.png

Slackはこの記事を見て、登録してみてください。
SlackのWebhook URL取得手順
Slack↓↓↓↓
スクリーンショット 2019-10-08 午後8.56.50.png

ここで出るエラー

  • Permission Error
    • APIキー を見直しましょう
    • DeployGate: Owner Name には、グループ名を記述してください!自分のアカウント名書いてて、エラー出しました?

各種設定画面

載せることができる範囲で公開します。

Code Signing

スクリーンショット 2019-10-08 午後8.57.41.png

Secrets

スクリーンショット 2019-10-08 午後8.59.39.png

Env Vars

スクリーンショット 2019-10-08 午後9.00.14.png

こっちは特に設定していない。
スクリーンショット 2019-10-08 午後9.01.06.png

Slack から実行

/bitrise_oshidori_ios b:master|w:Oshidori_iOS_DeployGate を Slack から実行すると、

スクリーンショット 2019-10-08 午後9.06.19.png

キターーーーーーーーーーーーーーー????????????

DeployGate を確認すると、

スクリーンショット 2019-10-08 午後9.06.04.png

ヨッシャーーーーーーーーーーーーーー????????????

Build Succeeded! はとても気持ちいいのでぜひ体験してみてください☺️

さいごに

簡単にやってる感じですが、これはエラーを合計150回以上出した体験の賜物です。(会社+この記事作成にあたって)
タイトルでは100回以上とちょっと減らしました(なんで)
会社のは見せれないですが、今回の記事を書くために行ったビルド回数は13回ですね。頑張った?
bitrise_success.png

会社では13個のアプリを Bitrise で Deploygate と AppStoreConnect に上げる設定を作成しました。
多かったので140回以上エラー出してます。(workflowだけで30個以上作った)
そしてエラーの回数だけ、全社メールが飛んでいたことを後から知りました。笑
みんな、「どんだけエラーメール飛んでくるんや」って思ってただろうな。。。
無事に終わって何よりです?

皆さんもガンガンエラー出して、Bitriseの使い方を学んでいきましょう?

Bitrise とても使いやすくて良かったです☺️
公式のドキュメントもとても良いです!ほぼ書いてあるし。読みやすい。
Twitter で呟いたら公式アカウントが絡んでくるのも面白くて好感が持てました笑

参考文献まとめ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む