20200806のiOSに関する記事は15件です。

Fastlane Match利用中にProvisioning ProfileをApple Developer Program上で誤って削除しちゃったら

Apple Developer Program上で複数のApp IDを管理してると、期限切れや利用不可の証明書とProvisioning Profileを一掃してくれるコマンドfastlane match nukeが使えなくてハマったのでメモです

前提

  • Fastlane Matchで証明書/Provisioning Profileを管理
  • 1つのApple Developerアカウントで複数のアプリ(App ID)を管理

現象

Fastlane Matchで生成されたProvisioning ProfileをApple Developer Programで直接削除したら、

$ fastlane match development

コマンドを実行したときに以下のエラーが出てきた

[15:50:22]: Provisioning profile 'XXXXX' is not available on the Developer Portal
[15:50:22]: for the user abc@abc.com
[15:50:22]: Make sure to use the same user and team every time you run 'match' for this
[15:50:22]: Git repository. This might be caused by deleting the provisioning profile on the Dev Portal

[!] To reset the provisioning profiles of your Apple account, you can use the fastlane match nuke feature, more information on https://docs.fastlane.tools/actions/match/

fastlane match nukeを実行すれば解決するよ」とは教えてくれるが、私の環境ではnukeはできない。
なぜならば、Apple Developer Program上で複数種類のApp IDを管理している状態だと、nukeはApp ID関係なくあらゆる期限切れの証明書やProvisioning profileを削除しちゃうから使えない。(関係ないApp ID関連の物まで消しちゃう)

対応

Matchfilegit_url("git@github.com:XXX/XXX.git)で指定してるプライベートレポジトリ上で、Developer Program上で消してしまったProvisioning profileを直接削除すると、matchコマンドがまた使えるようになる

参考URL

https://stackoverflow.com/questions/37520489/what-should-i-do-with-fastlane-match-after-certificate-revoked

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

HtmlタグでStringを装飾する方法

  • htmlタグをStringで書いて
  • そのStringをData変換
  • NSMutableAttributedString(data:options:documentAttributes)で装飾する
    • options に documentType.html を指定
let str = "<i>testText</i>"
let stringWithBaseFont = NSString(format:"<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size: \(22)\">%@</span>" as NSString, str)

stringWithBaseFont.data(using: String.Encoding.unicode.rawValue, allowLossyConversion: true)!

if let attributedString = try? NSMutableAttributedString(
    data: stringWithBaseFont.data(using: String.Encoding.unicode.rawValue, allowLossyConversion: true)!,
    options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue],
    documentAttributes: nil) {
    attributedString.addAttribute(.foregroundColor, value: UIColor.red, range: NSRange(location: 0, length: attributedString.length))
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Create MLで自動車部品の不良品検知

Create MLで100%検知

目視できるレベルの金属部品の表面異常検知であれば、 Create MLで十分な高精度を達成できます。
MLBoysで自動車部品メーカーとの技術研究を行い、
Create MLで100%の検知結果を出しました。

現場で使えるのか

傷は1〜4mm程度。
良品.png 不良品.png
(左)良品 / (右)不良品(四角い影が「圧痕」という傷)

良品30、不良品30のデータでの実験となります。

現場では99%の検知能力が求められます。
製造現場では90%の分類精度であっても不十分です。
大量の再検査コストがかかり、自動化の意味がなくなってしまうのです。

Create MLの画像認識モデルは、(模様のようなものではなく)物体の種類分類データセットによって事前学習されているため、細かい模様のような傷には適用できないのではないかと当初は考えました。

そのため当初は、Pythonの画像分類ネットワークを初期値からトレーニングするか、抽象度の高い事前学習層だけを用いて転移学習させる必要があると覚悟しました。
それでもダメなら、金属表面専用の最新研究を用いる。

ただ、とりあえず試す意味でCreate MLにかけてみると、わりあいあっけなく精度100%を達成しました。
スクリーンショット 2020-08-06 1.32.21.png

金属表面を分類する際のコツ

重要なのは、データセットを可能な限り一貫した画像にすることです。
モデルに傷の有無だけに集中してもらうイメージで取り組みました。

1、フォーカスする領域にクロップする

部品全体の画像を一気にモデルにかけてしまうと、ランダムに近い結果しか得られませんでした。
幸い、今回の部品は傷のつく場所が部品の一部分に集中していたので、その部分だけをクロップして使用しました。
複数箇所に傷がある場合は、一定の形状や角度ごとに部品の部分を区別して、各々でモデルを作成した方が高精度が望めます。

2、撮像環境を一定にする

金属は光の反射があるので、部分による明暗が出てしまいます。
撮像環境を一定にすることで、反射のばらつきは無視できます。
カメラと部品の位置を固定して撮影します。
特別な照明は必要ありません。

3、データ拡張を慎重に行う。

データ拡張なしでCreate MLでトレーニングしたところ、Training正解率は100%、Validation(検証)正解率は70%程度でした。
トレーニング正解率と検証正解率が乖離するのは過学習のサインです。
一般に、過学習はデータセットが十分ではない時に起こります。
十分なデータを得ることが難しい場合は、データ拡張を用いてデータセットを水増しします。
ただし、やみくもにデータ拡張をすればいいというものでもありません。
Create MLには
Add Noise、Blur、Crop、Flip、Rotate
というデータ拡張オプションがありますが、今回は、たとえばrotateを適用して画像をランダムな角度で回転させてデータを水増ししたところ、むしろ正解率が下がりました。
Flipだけを用いたところ、正解率100%を達成できました。

画像の性質上、画像のz軸で回転させると、本来は一方向であった光の反射や影や金属の表面の筋がバラバラの向きになってしまい、ノイズとして無視したいものを画像の特徴として捉えてしまうのだと思います。

現場への導入に必要なこと

1、部品表面全体を画像認識する必要があります

部品を回転させながら撮像します。
2つ方法があります。
・時系列で回転させた表面を一枚の画像としてまとめる方法。
・回転させながら動画を撮って毎フレーム解析する方法です。
Create MLの軽量モデルならエッジデバイスでも毎フレーム解析が可能なので、後者がとっつきやすいように思います。

2、不良品を排除する機器に信号を送る必要があります

BlueToothなどの形で通信する必要があります。

3、過検出を防ぐ

現場で発生する埃や繊維、白粉といった「不良品ではないが表面異常としてうつるノイズ」を無視する必要があります。
これらのノイズが原因で「不良品」として認識してしまうと、良品が大量に弾かれてしまい、結局再検査の人員コストがかかります。
過検出を防ぐには、CIFilter等を用いて情報をエッジのみにするなどして、ノイズを目立たないように、傷が目立つように画像を前処理することが有効です。
WWDC 2020のセッション Explore Computer Vision APIs が参考になります。
スクリーンショット 2020-08-06 1.59.18.png
(写真)フィルターで情報量を削った金属表面

結論

目視できるレベルの不良品検出であれば、Create MLで十分に対応できます。
少なくとも、Pythonモデルで試行錯誤する前に、手軽に試してみてる価値はあります。。

スクリーンショット 2020-08-06 8.25.52.png
機械学習関連の情報を発信しています。
MLBoysだいすけ https://twitter.com/JackdeS11
MLBoysゆうじ https://twitter.com/oka_yuuji

Core MLやCreate ML、Visionを使ったアプリを作っています。
MLBoys:mlboys.d.yu@gmail.com
だいすけ:rockyshikoku@gmail.com

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

Dictionary<Key, Value>型

 Dictionary<Key, Value>型

Dictionary<Key, Value>型は、
キー:で分けて、[]で囲みます。

var screenSizesInInches: Dictionary<String, Double>
    = ["iPhone 7": 4.7, "iPhone 7 Plus": 5.2, "iPad Pro": 12.9]
var screenSizesInInches: Dictionary<String, Double>
    = ["キー": , "キー": , "キー": ]

スマホの、インチ(Inchi)数?

連想配列

-Dictionaryは、連想配列らしいです。

『連想配列』。 辞書(英語: dictionary)、ハッシュ(英語: hash)、マップ(英語: map)とも呼ばれる。

.

フツーの配列は、インデックス(=始点からのズレ。) で、値を特定。
連想配列では、キーによって、値を特定。

連想配列(Wikipedia)

 まとめ休憩?

-Dictionary(=辞書)型は、キーと値がペア。
-キーをもとに、値を特定。
-キーが他のものと被るのは、NG。(値はOK)

 コード ?

さっき書いたコードの続き。

Keyを指定して、値をGET

import UIKit

var screenSizesInInches: Dictionary<String, Double>
    = ["iPhone 7": 4.7, "iPhone 7 Plus": 5.2, "iPad Pro": 12.9]

screenSizesInInches["iPhone 7"] // 4.7
screenSizesInInches[4.7]        // No exact matches in call to subscript

という感じで、

-Keyを指定すると、値をGETできるけど、
-値を指定したら、下記のエラー。

No exact matches in call to subscript
「インデックスの呼び出しにて、マッチするもの存在しないよ」 と言われました?

『キーをもとに、値を特定』するのが、Dictionaryの仕事なので、
妥当な結果だと思います。?

値の削除

2パターン。

-nilを代入
-removeValue(forKey: "キー")

screenSizesInInches["iPhone 7"] = nil
screenSizesInInches.removeValue(forKey: "iPhone 7 Plus")
  // どちらでも可。

※waiting for key-inで、「キーの入力待ち」 的な感じで、
forKeyfor は、接続詞だと思ふ。

 おわりに

 PlayGround、シンプルで秀逸。

 参考サイト

【swift入門 文法編】辞書(Dictionary型)をマスターする

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

Create MLで自動車部品の不良品検知

Create MLで100%検知

目視できるレベルの金属部品の表面異常検知であれば、 Create MLで十分な高精度を達成できます。

Pythonに潜って専用モデルを探したり、カスタムモデルをつくる必要はありません。

我々が自動車部品メーカーとの技術研究で100%の検知結果を出したCreate MLでの画像分類タスクの取り組みについて紹介します。

Create MLは表面異常検知の現場で使えるのか

自動車に用いられている4cm程度の細長い部品の表面異常検知をおこないました。
傷の大きさは1〜4mm程度。
良品.png 不良品.png
(左)良品 / (右)不良品(中央に斜めに走っている四角い影が「圧痕」という傷)

実際に出荷されている部品であるため、部品サンプルはたくさんは望めず。
良品30本、不良品30本のデータでの実験となります。

この分野では90%の分類精度であっても不十分です。
大量の再検査コストがかかり、自動化の意味がなくなってしまうのです。
現場では99%の検知能力が求められます。

Create MLの画像認識モデルは、(模様のようなものではなく)物体の種類分類データセットによって事前学習されているため、細かい模様のような傷には適用できないのではないかと当初は考えました。

そのため当初は、Pythonの画像分類ネットワークを初期値からトレーニングするか、抽象度の高い事前学習層だけを用いて転移学習させる必要があると覚悟しました。
それでもダメなら、金属表面専用の最新研究を用いる。

ただ、とりあえず試す意味でCreate MLにかけてみると、わりあいあっけなく精度100%を達成しました。
スクリーンショット 2020-08-06 1.32.21.png

金属表面を分類する際のコツ

重要なのは、データセットを可能な限り(傷以外の)ばらつきのない画像にすることです。
モデルに傷の有無だけに集中してもらうイメージで取り組みました。

1、フォーカスする領域にクロップする

部品全体の画像を一気にモデルにかけてしまうと、ランダムに近い結果しか得られませんでした。
幸い、今回の部品は傷のつく場所が部品の一部分に集中していたので、その部分だけをクロップして使用しました。
複数箇所に傷がある場合は、一定の形状や角度ごとに部品の部分を区別して、各々でモデルを作成した方が高精度が望めます。

2、撮像環境を一定にする

金属表面が光の反射があるので、どうしても部分による明暗が出てしまいます。
撮像環境をできる限り一定にすることで、反射のばらつきは無視して傷のみを学習できます。
その程度の能力はCreate MLにはあります。
一般住宅内のLED照明の下で、カメラと部品を一定の位置に固定して撮影することで、上記の精度を達成できました。
もちろん、傷が濃く映るような明るさが理想です。ただそのために特別な証明は必要ないということです。

3、データ拡張を慎重に行う。

データ拡張なしでCreate MLでトレーニングしたところ、Training正解率は100%、Validation(検証)正解率は70%程度でした。
トレーニング正解率と検証正解率が乖離するのは過学習のサインです。
一般に、過学習はデータセットが十分ではない時に起こります。
十分なデータを得ることが難しい場合は、データ拡張を用いてデータセットを水増しします。
ただし、やみくもにデータ拡張をすればいいというものでもありません。
Create MLには
Add Noise、Blur、Crop、Flip、Rotate
というデータ拡張オプションがありますが、今回は、たとえばrotateを適用して画像をランダムな角度で回転させてデータを水増ししたところ、むしろ正解率が下がりました。
Flipだけを用いたところ、正解率100%を達成できました。

画像の性質上、画像のz軸で回転させると、本来は一方向であった光の反射や影や金属の表面の筋がバラバラの向きになってしまい、ノイズとして無視したいものを画像の特徴として捉えてしまうのだと思います。

現場への導入に必要なこと

1、部品表面全体を画像認識する必要があります

部品を回転させながら撮像します。
2つ方法があります。
・時系列で回転させた表面を一枚の画像としてまとめる方法。
・回転させながら動画を撮って毎フレーム解析する方法です。
Create MLの軽量モデルならエッジデバイスでも毎フレーム解析が可能なので、後者がとっつきやすいように思います。

2、不良品を排除する機器に信号を送る必要があります

BlueToothなどの形で通信する必要があります。

3、過検出を防ぐ

現場で発生する埃や繊維、白粉といった「不良品ではないが表面異常としてうつるノイズ」を無視する必要があります。
これらのノイズが原因で「不良品」として認識してしまうと、良品が大量に弾かれてしまい、結局再検査の人員コストがかかります。
過検出を防ぐには、CIFilter等を用いて情報をエッジのみにするなどして、ノイズを目立たないように、傷が目立つように画像を前処理することが有効です。
WWDC 2020のセッション Explore Computer Vision APIs が参考になります。
スクリーンショット 2020-08-06 1.59.18.png
(写真)フィルターで情報量を削った金属表面

結論

目視できるレベルの不良品検出であれば、Create MLで十分に対応できます。
少なくとも、Pythonモデルで試行錯誤する前に、手軽に試してみてる価値はあります。。

スクリーンショット 2020-08-06 8.25.52.png
機械学習関連の情報を発信しています。
MLBoysだいすけ https://twitter.com/JackdeS11
MLBoysゆうじ https://twitter.com/oka_yuuji

Core MLやCreate ML、Visionを使ったアプリを作っています。
mlboys.d.yu@gmail.com

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

[swift5]エラーUse of unresolved identifier 'FirebaseApp'の対処法

エラー内容

FacebookログインをFirebaseを用いて実装しようと思い、コードを書いている際に発生したエラーです。記述コードは以下の通り。

AppDelegate.swift
import UIKit
import Firebase  //このコードを記述

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        FirebaseApp.configure()  //このコードを記述
        return true
    }

FirebaseApp.configure()の箇所にUse of unresolved identifier 'FirebaseApp'というエラーが発生する。

環境▼
swift5
Xcode 11.6

原因

どうやらpod 'Firebase/Core'をインストールした際に、古いバージョンでインストールされていた模様。FirebaseAppはバージョン4以上でないと定義されていないらしい。

なので、pod 'Firebase/Core'のバージョンを更新すれば解決できそう!

対処法

①対象アプリのディレクトリ内に存在するPodfile.lockファイルを削除。
②ターミナルで以下のコードを実行し、podを最新状態へ更新する。(アプリのディレクトリ

ターミナル.
pod repo update
ターミナル.
pod update

③続いて依存関係を考慮したいので、podfileにはpod 'Firebase/Core'だけを記述して以下を実行。

ターミナル.
pod install

これで最新のpod 'Firebase/Core'と、関連のライブラリがインストールされるので、Xcodeで確認してみて下さい。エラーが解決されていると思います。

なお、一度最新のpodをインストールすればPodfile.lockに最新バージョンが固定される為、他のpodを入れても問題ないので安心して下さい!

最後に

今回のエラーはswift初学者が高確率で遭遇するエラーだと思われます。
是非参考にして下さい!

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

iOS14での写真アプリへのアクセスについて

はじめに

※ 本記事はWWDC2020で発表された内容を元に作成しております。
※ 記事中の画像はWWDC2020での発表のものを引用させていただいております。

iOS14から写真アプリへのアクセス方法に更新があるため、今回調査してまとめてみました。

写真アプリへのアクセスレベルの指定

iOS14から写真アプリへの認証を確認する際にはアクセスレベルを指定することが必要になります。
これには新たに定義された列挙型のPHAccessLevelを用います。
これによりアクセスレベルを追加のみ.addOnly、もしくは読み込み/書き込み.readWriteに指定することができるようになりました。

スクリーンショット 2020-08-05 22.36.12.png

見た目の変化

iOS13以前では新規でアプリをリリースしてそのアプリ内で写真を撮った場合、単に写真アプリへのアクセスを許可するかどうかの表示となっていたと思います。

iOS14ではアクセスのレベルがより細かく設定できるようになりました。
これにより、

写真の追加のみ
 ├ 許可する
 └ 許可しない

読み込み/書き込み
 ├ 全ての写真を対象
 ├ 選択した写真のみ対象
 └ 許可しない

といった選択肢になりました。
PHAccessLevel.addOnlyにしていると左画像、.readWriteにしていると右画像のようになります。
スクリーンショット 2020-08-05 22.21.17.png スクリーンショット 2020-08-05 22.21.37.png

コードでの対応

iOS13まではPHPhotoLibrary.authorizationStatus()に引数はありませんでしたが、iOS14では下記コードの中段のように引数にアクセスレベルを宣言する必要があります。
PHAccessLevelを用いたコード

まとめ

iOS14からはPHAccessLevelの登場により写真アプリのアクセスに影響が現れるので、アプリの用途に応じて認証の.addOnly.readWriteを宣言する必要があります。
抜け漏れをせずに対応していきましょう。

参考

  1. Handle the Limited Photos Library in your app
  2. Photo library changes in iOS 14
  3. authorizationStatus() | Apple Developer Documentation
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOS14での写真アプリへのアクセスレベルについて

はじめに

※ 本記事はWWDC2020で発表された内容を元に作成しております。
※ 記事中の画像はWWDC2020での発表のものを引用させていただいております。

iOS14から写真アプリへのアクセス方法に更新があるため、今回調査してまとめてみました。

写真アプリへのアクセスレベルの指定

iOS14から写真アプリへの認証を確認する際にはアクセスレベルを指定することが必要になります。
これには新たに定義された列挙型のPHAccessLevelを用います。
これによりアクセスレベルを追加のみ.addOnly、もしくは読み込み/書き込み.readWriteに指定することができるようになりました。

スクリーンショット 2020-08-05 22.36.12.png

見た目の変化

iOS13以前では新規でアプリをリリースしてそのアプリ内で写真を撮った場合、単に写真アプリへのアクセスを許可するかどうかの表示となっていたと思います。

iOS14ではアクセスのレベルがより細かく設定できるようになりました。
これにより、

写真の追加のみ
 ├ 許可する
 └ 許可しない

読み込み/書き込み
 ├ 全ての写真を対象
 ├ 選択した写真のみ対象
 └ 許可しない

といった選択肢になりました。
PHAccessLevel.addOnlyにしていると左画像、.readWriteにしていると右画像のようになります。
スクリーンショット 2020-08-05 22.21.17.png スクリーンショット 2020-08-05 22.21.37.png

コードでの対応

iOS13まではPHPhotoLibrary.authorizationStatus()に引数はありませんでしたが、iOS14では下記コードの中段のように引数にアクセスレベルを宣言する必要があります。
PHAccessLevelを用いたコード

まとめ

iOS14からはPHAccessLevelの登場により写真アプリのアクセスに影響が現れるので、アプリの用途に応じて認証の.addOnly.readWriteを宣言する必要があります。
抜け漏れをせずに対応していきましょう。

参考

  1. Handle the Limited Photos Library in your app
  2. Photo library changes in iOS 14
  3. authorizationStatus() | Apple Developer Documentation
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Stack Viewは便利ですね?

 Stack Viewは便利ですね。

Swiftを始めて、3日目。
Stackについて学んだので、簡単にまとめ。

-【Swift】超便利StackViewの実践的使い方!まだAutoLayoutで消耗してるの?
-遅ればせながら UIStackView 入門

と言っても、他サイト引用です。?

-Stack

「レイアウトの修正が大変...」というAuto Layoutの欠点を解決してくれます。
 最低限のAutoLayoutの設定で済む、良心的な機能です。

 補足

右下に5個並んでるボタンについて、ちょっと補足。

スクリーンショット 2020-08-06 8.24.29.png

-Stackの削除

Embed In(一番右) にて、Unembed

スクリーンショット 2020-08-06 8.41.25.png

-Constraintの更新・削除

Resolve Auto Layout Issues(右から2番目) にて、
Update~ が更新。
Clear~ が削除。

Updateすると、上記画像のオレンジ色の「所定のConstraintからズレてるよ!」的な
警告が消える。

スクリーンショット 2020-08-06 8.54.13.png

-元のConstraintの位置に戻す

Update Frames(一番左)
(名称が "Return Frames" じゃない理由が謎。?)

※使用環境

 iOS8以前では、Stack View は使用できないみたいです。
 iOS9以上で利用可能。

 おまけ

View Controllerの召喚。
オブジェクトライブラリで、View Controllerと検索。
スクリーンショット 2020-08-06 8.20.05.png

Is Initial View Controllerのチェックを忘れずに。
Runしたときの、EntryPoint になります。(最初に始まる画面になる。)

※当たり前ですが、EntryPointの複数指定は無理なので、
他のView Controllerでのチェックは自動で消えてくれます?

スクリーンショット 2020-08-06 9.31.30.png

オブジェクトライブラリ表示。

-Command + shift + L  
(Option長押し、表示を維持)
(一回ドラッグ&ドロップすれば、あとは長押し続けなくても表示を維持)

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3638333739352f31353632373235332d303566322d346532352d326538392d6165326438643839306134302e706e67.png

 終わりに。

ネイティブアプリ開発は、エミュレーターが楽しい。
PC画面上にスマホがあるという感動 ?

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

Create MLで不良品検知

Create MLで100%検知

目視できるレベルの金属部品の表面異常検知であれば、 Create MLで十分な高精度を達成できます。

Pythonに潜って専用モデルを探したり、カスタムモデルをつくる必要はありません。

我々が自動車部品メーカーとの技術研究で100%の検知結果を出したCreate MLでの画像分類タスクの取り組みについて紹介します。

Create MLは表面異常検知の現場で使えるのか

自動車に用いられている4cm程度の細長い部品の表面異常検知をおこないました。
傷の大きさは1〜4mm程度。
良品.png 不良品.png
(左)良品 / (右)不良品(中央に斜めに走っている四角い影が「圧痕」という傷)

実際に出荷されている部品であるため、部品サンプルはたくさんは望めず。
良品30本、不良品30本のデータでの実験となります。

この分野では90%の分類精度であっても不十分です。
大量の再検査コストがかかり、自動化の意味がなくなってしまうのです。
現場では99%の検知能力が求められます。

Create MLの画像認識モデルは、(模様のようなものではなく)物体の種類分類データセットによって事前学習されているため、細かい模様のような傷には適用できないのではないかと当初は考えました。

そのため当初は、Pythonの画像分類ネットワークを初期値からトレーニングするか、抽象度の高い事前学習層だけを用いて転移学習させる必要があると覚悟しました。
それでもダメなら、金属表面専用の最新研究を用いる。

ただ、とりあえず試す意味でCreate MLにかけてみると、わりあいあっけなく精度100%を達成しました。
スクリーンショット 2020-08-06 1.32.21.png

金属表面を分類する際のコツ

重要なのは、データセットを可能な限り(傷以外の)ばらつきのない画像にすることです。
モデルに傷の有無だけに集中してもらうイメージで取り組みました。

1、フォーカスする領域にクロップする

部品全体の画像を一気にモデルにかけてしまうと、ランダムに近い結果しか得られませんでした。
幸い、今回の部品は傷のつく場所が部品の一部分に集中していたので、その部分だけをクロップして使用しました。
複数箇所に傷がある場合は、一定の形状や角度ごとに部品の部分を区別して、各々でモデルを作成した方が高精度が望めます。

2、撮像環境を一定にする

金属表面が光の反射があるので、どうしても部分による明暗が出てしまいます。
撮像環境をできる限り一定にすることで、反射のばらつきは無視して傷のみを学習できます。
その程度の能力はCreate MLにはあります。
一般住宅内のLED照明の下で、カメラと部品を一定の位置に固定して撮影することで、上記の精度を達成できました。

3、データ拡張を慎重に行う。

データ拡張なしでCreate MLでトレーニングしたところ、Training精度は100%、Validation(検証)精度は70%程度でした。
トレーニング正解率と検証正解率が乖離するのは過学習のサインです。
一般に、過学習はデータセットが十分ではない時に起こります。
十分なデータを得ることが難しい場合は、データ拡張を用いてデータセットを水増しします。
ただし、やみくもにデータ拡張をすればいいというものでもありません。
Create MLには
Add Noise、Blur、Crop、Flip、Rotate
というデータ拡張オプションがありますが、今回は、たとえばrotateを適用して画像をランダムな角度で回転させてデータを水増ししたところ、むしろ正解率が下がりました。
Flipだけを用いたところ、100%精度を達成できました。

画像の性質上、画像のz軸で回転させると、本来は一方向であった光の反射や影や金属の表面の筋がバラバラの向きになってしまい、ノイズとして無視したいものを画像の特徴として捉えてしまうのだと思います。

現場への導入に必要なこと

1、部品表面全体を画像認識する必要があります

部品を回転させながら撮像します。
2つ方法があります。
・時系列で回転させた表面を一枚の画像としてまとめる方法。
・回転させながら動画を撮って毎フレーム解析する方法です。
Create MLの軽量モデルならエッジデバイスでも毎フレーム解析が可能なので、後者がとっつきやすいように思います。

2、不良品を排除する機器に信号を送る必要があります

BlueToothなどの形で通信する必要があります。

3、過検出を防ぐ

現場で発生する埃や繊維、白粉といった「不良品ではないが表面異常としてうつるノイズ」を無視する必要があります。
これらのノイズが原因で「不良品」として認識してしまうと、良品が大量に弾かれてしまい、結局再検査の人員コストがかかります。
過検出を防ぐには、CIFilter等を用いて情報をエッジのみにするなどして、ノイズを目立たないように、傷が目立つように画像を前処理することが有効です。
WWDC 2020のセッション Explore Computer Vision APIs が参考になります。
スクリーンショット 2020-08-06 1.59.18.png
(写真)フィルターで情報量を削った金属表面

結論

目視できるレベルの不良品検出であれば、Create MLで十分に対応できます。
少なくとも、Pythonモデルで試行錯誤する前に、手軽に試してみてる価値はあります。。

スクリーンショット 2020-08-06 8.25.52.png
機械学習関連の情報を発信しています。
MLBoysだいすけ https://twitter.com/JackdeS11
MLBoysゆうじ https://twitter.com/oka_yuuji

Core MLやCreate ML、Visionを使ったアプリを作っています。
rockyshikoku@gmail.com

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

Create MLで自動車部品の不良品検知

Create MLで100%検知

目視できるレベルの金属部品の表面異常検知であれば、 Create MLで十分な高精度を達成できます。

Pythonに潜って専用モデルを探したり、カスタムモデルをつくる必要はありません。

我々が自動車部品メーカーとの技術研究で100%の検知結果を出したCreate MLでの画像分類タスクの取り組みについて紹介します。

Create MLは表面異常検知の現場で使えるのか

自動車に用いられている4cm程度の細長い部品の表面異常検知をおこないました。
傷の大きさは1〜4mm程度。
良品.png 不良品.png
(左)良品 / (右)不良品(中央に斜めに走っている四角い影が「圧痕」という傷)

実際に出荷されている部品であるため、部品サンプルはたくさんは望めず。
良品30本、不良品30本のデータでの実験となります。

この分野では90%の分類精度であっても不十分です。
大量の再検査コストがかかり、自動化の意味がなくなってしまうのです。
現場では99%の検知能力が求められます。

Create MLの画像認識モデルは、(模様のようなものではなく)物体の種類分類データセットによって事前学習されているため、細かい模様のような傷には適用できないのではないかと当初は考えました。

そのため当初は、Pythonの画像分類ネットワークを初期値からトレーニングするか、抽象度の高い事前学習層だけを用いて転移学習させる必要があると覚悟しました。
それでもダメなら、金属表面専用の最新研究を用いる。

ただ、とりあえず試す意味でCreate MLにかけてみると、わりあいあっけなく精度100%を達成しました。
スクリーンショット 2020-08-06 1.32.21.png

金属表面を分類する際のコツ

重要なのは、データセットを可能な限り(傷以外の)ばらつきのない画像にすることです。
モデルに傷の有無だけに集中してもらうイメージで取り組みました。

1、フォーカスする領域にクロップする

部品全体の画像を一気にモデルにかけてしまうと、ランダムに近い結果しか得られませんでした。
幸い、今回の部品は傷のつく場所が部品の一部分に集中していたので、その部分だけをクロップして使用しました。
複数箇所に傷がある場合は、一定の形状や角度ごとに部品の部分を区別して、各々でモデルを作成した方が高精度が望めます。

2、撮像環境を一定にする

金属表面が光の反射があるので、どうしても部分による明暗が出てしまいます。
撮像環境をできる限り一定にすることで、反射のばらつきは無視して傷のみを学習できます。
その程度の能力はCreate MLにはあります。
一般住宅内のLED照明の下で、カメラと部品を一定の位置に固定して撮影することで、上記の精度を達成できました。
もちろん、傷が濃く映るような明るさが理想です。ただそのために特別な証明は必要ないということです。

3、データ拡張を慎重に行う。

データ拡張なしでCreate MLでトレーニングしたところ、Training正解率は100%、Validation(検証)正解率は70%程度でした。
トレーニング正解率と検証正解率が乖離するのは過学習のサインです。
一般に、過学習はデータセットが十分ではない時に起こります。
十分なデータを得ることが難しい場合は、データ拡張を用いてデータセットを水増しします。
ただし、やみくもにデータ拡張をすればいいというものでもありません。
Create MLには
Add Noise、Blur、Crop、Flip、Rotate
というデータ拡張オプションがありますが、今回は、たとえばrotateを適用して画像をランダムな角度で回転させてデータを水増ししたところ、むしろ正解率が下がりました。
Flipだけを用いたところ、正解率100%を達成できました。

画像の性質上、画像のz軸で回転させると、本来は一方向であった光の反射や影や金属の表面の筋がバラバラの向きになってしまい、ノイズとして無視したいものを画像の特徴として捉えてしまうのだと思います。

現場への導入に必要なこと

1、部品表面全体を画像認識する必要があります

部品を回転させながら撮像します。
2つ方法があります。
・時系列で回転させた表面を一枚の画像としてまとめる方法。
・回転させながら動画を撮って毎フレーム解析する方法です。
Create MLの軽量モデルならエッジデバイスでも毎フレーム解析が可能なので、後者がとっつきやすいように思います。

2、不良品を排除する機器に信号を送る必要があります

BlueToothなどの形で通信する必要があります。

3、過検出を防ぐ

現場で発生する埃や繊維、白粉といった「不良品ではないが表面異常としてうつるノイズ」を無視する必要があります。
これらのノイズが原因で「不良品」として認識してしまうと、良品が大量に弾かれてしまい、結局再検査の人員コストがかかります。
過検出を防ぐには、CIFilter等を用いて情報をエッジのみにするなどして、ノイズを目立たないように、傷が目立つように画像を前処理することが有効です。
WWDC 2020のセッション Explore Computer Vision APIs が参考になります。
スクリーンショット 2020-08-06 1.59.18.png
(写真)フィルターで情報量を削った金属表面

結論

目視できるレベルの不良品検出であれば、Create MLで十分に対応できます。
少なくとも、Pythonモデルで試行錯誤する前に、手軽に試してみてる価値はあります。。

スクリーンショット 2020-08-06 8.25.52.png
機械学習関連の情報を発信しています。
MLBoysだいすけ https://twitter.com/JackdeS11
MLBoysゆうじ https://twitter.com/oka_yuuji

Core MLやCreate ML、Visionを使ったアプリを作っています。
mlboys.d.yu@gmail.com

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

iOSデバイスからAzure上の仮想ネットワークにP2S接続する

背景

iPhoneやiPadから、Azure上の仮想ネットワークにP2S接続(ポイント対サイト接続)したくなったのだが、Microsoftのドキュメントは要点が掴みづらくてわかりにくいし(機械翻訳の影響か?)、Google先生に聞いてもドンピシャな回答が見つけられなかったので、その手順を記す。

調査

そもそも、iOSデバイスでAzureにP2S接続できるのか?

公式ドキュメントには、

ポイント対サイト VPN では、次のいずれかのプロトコルを使用できます。

  • SSL/TLS ベースの VPN プロトコルである OpenVPN® プロトコル。 ほとんどのファイアウォールは、TLS で使用されるアウトバウンド TCP ポート 443 を開いているため、TLS VPN ソリューションはファイアウォールを通過できます。 OpenVPN は、Android、iOS (バージョン 11.0 以上)、Windows、Linux、および Mac デバイス (OSX バージョン 10.13 以上) から接続する際に使用できます。

とあるので、iOS 11.0以降ならOpenVPNが使えるのでP2S接続が可能。

制限は?

上記の情報から、iOSデバイスをP2S接続するにはOpenVPNを使用することがわかった。

しかし、ゲートウェイの SKUを確認すると、最も安価なBasicではOpenVPNが使用できない事がわかる。
ついでにいうと、Linuxを繋ぎたい場合もOpenVPN必須なので、BasicではNG。
また、Macを繋ぎたい場合はIKEv2が必要なので、BasicではNG。
つまり、BasicでつながるのはWindowsのみ。

ということで、iOS/Mac/LinuxをP2S接続したい場合はVpnGw1以上を選択する必要がある。

説明の前提とする環境

以下のクライアント環境から、仮想ネットワーク環境に対してP2S接続する前提で記載する。

環境 アドレス範囲
仮想ネットワーク 172.16.1.0/24
クライアント (iOS) 10.0.0.0/24

クライアント環境と仮想ネットワーク環境とで、使用しているアドレス範囲に重複があると接続できないので、あらかじめどちらかのアドレス範囲を変更しておく必要がある。

また、後ほど登場するゲートウェイサブネットや、仮想ネットワークゲートウェイのアドレスプールも、これらのアドレス範囲と重複することが許されないので要注意。

手順

1. 接続先の仮想ネットワークと仮想マシンをデプロイする

これについては迷うこともないと思うので、説明は割愛する。

仮想ネットワークについては、ほとんどが既存の仮想ネットワークに接続したいという要件だと思うので省略することになると思う。

仮想マシンは、P2S接続確立後にpingやsshなどで接続確認するときに使う。
既存の仮想マシンを流用して構わなければ省略。

2. 接続先の仮想ネットワークにアドレス空間を追加する

P2S接続を実現するには、ゲートウェイサブネットを置くためのアドレス空間が必要になる。
既存のアドレス空間に/28の範囲を確保できるだけの余力があれば省略可能。

例えば、

アドレス空間 備考
172.16.1.0/24 ← 既存のアドレス空間
172.16.2.0/24 追加のアドレス空間

3. 仮想ネットワークゲートウェイをデプロイする

  1. Azure Portal上の+リソースの作成をクリック
  2. 検索バーにvpn gatewayと入力
  3. 候補の仮想ネットワークゲートウェイを選択し、作成をクリック
  4. 下記を参考に設定

    設定 備考
    名前 任意の名前を設定
    地域 接続先の仮想ネットワークと同じリージョンを選択
    ゲートウェイの種類 VPN
    SKU VpnGw1 Basic以外を選択
    仮想ネットワーク 接続先の仮想ネットワークを選択
    ゲートウェイ サブネットのアドレス範囲 172.16.2.0/28 '/28'の範囲が確保できていれば十分
    パブリックIPアドレス VPNゲートウェイに設定されるパブリックIP。
    既存の余剰IPがなければ作る。
  5. デプロイ(待ち時間に次の手順を実施しておく)

4. 証明書の生成とエクスポート

公式ドキュメントのPowerShell を使用したポイント対サイトの証明書の生成とエクスポートを参考に、別途別リージョンに構築しておいた Windows 10 の仮想マシン上で作業を行った。
手元に、 Windows 10 もしくは Windows Server 2016 の環境があれば、そこで作業して構わない。
もし、Linux上で作業をする場合はこちらの手順らしい。(未検証)

実施すべき作業は、

  1. 自己署名ルート証明書の作成
  2. クライアント証明書の生成
  3. ルート証明書の公開キー (.cer) のエクスポート
  4. クライアント証明書 (.pfx) のエクスポート

5. ユーザーVPN構成の設定

  1. Azure Portalに戻って、デプロイした仮想ネットワークゲートウェイを開く
  2. 左側のメニューからユーザーVPN構成をクリック
  3. 下記を参考に設定

    設定 備考
    アドレスプール 192.168.0.0/24 他の登場人物と重複しないアドレス範囲を指定
    トンネルの種類 OpenVPN (SSL)
    認証の種類 Azure証明書
    ルート証明書 > 名前 任意の名前を設定
    ルート証明書 > 公開証明書データ 手順4−3で取得したルート証明書の公開キー文字列を貼り付け
  4. 保存

6. 構成ファイルのダウンロード

  1. 同画面でVPNクライアントのダウンロードをクリック
  2. Zipファイルを解凍

7. vpnconfig.ovpnの編集

  1. OpenVPNフォルダ配下の、vpnconfig.ovpnをテキストエディタで開いておく
  2. 手順4−4でエクスポートしておいたpfxファイルを使用して、WindowsかLinux上で下記のコマンドを実行する
openssl pkcs12 -in "filename.pfx" -nodes -out "profileinfo.txt"
  1. profileinfo.txtを開き、クライアント証明書の秘密鍵文字列公開鍵文字列を確認する
  2. 以下のように、秘密鍵文字列公開鍵文字列vpnconfig.ovpnに上書きする
vpnconfig.ovpn
    :
 前半部分は省略
    :

# P2S client certificate
# Please fill this field with a PEM formatted client certificate
# Alternatively, configure 'cert PATH_TO_CLIENT_CERT' to use input from a PEM certificate file.
<cert>
-----BEGIN CERTIFICATE-----
        :
 クライアント証明書の公開鍵文字列
        :
-----END CERTIFICATE-----
</cert>

# P2S client certificate private key
# Please fill this field with a PEM formatted private key of the client certificate.
# Alternatively, configure 'key PATH_TO_CLIENT_KEY' to use input from a PEM key file.
<key>
-----BEGIN PRIVATE KEY-----
        :
     秘密鍵の文字列
        :
-----END PRIVATE KEY-----
</key>

8. iOSデバイスにOpenVPN Connectアプリをインストールする

OpenVPN Connect

9. vpnconfig.ovpnをiOSデバイスにインストールする

  1. 転送したファイルをiOSデバイスで開く
  2. OpenVPN Connectアプリが開いてImport Profile画面になるのでADDをタップ
  3. ImportedProfile画面になるので、再度ADDをタップ

10. P2S接続の確立

OpenVPN ConnectアプリのProfile画面で、トグルボタンを有効に倒す。
これでP2SのVPN接続が確立する。
VPN接続中は、画面上部の電波マーク付近にVPNアイコンが表示される。

なお、複数のVPNプロファイルがインストールされている場合で、プロファイルを切り替えたいときは、OpenVPN Connectアプリからではなく、OSの設定画面(設定>VPN)から直接プロファイルの切り替えが必要になる場合もある。

10. 動作確認

接続先の仮想ネットワーク上の仮想マシンに対して、pingやssh接続をしてみる。

iPhoneやiPadには標準のターミナルアプリが無いが、a-Shellというアプリを使うとシェルを使用できるようになる。

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

String.split(separator:) で Xcode Previews がコケる

SwiftUIで画面を実装中していたらXcode Previewsで表示していたプレビューが突然できなくなった。

Diagnosticsを開くとこんなエラー

Compiling failed: global function '__designTimeString(_:fallback:)' requires that 'String.Element' (aka 'Character') conform to 'ExpressibleByStringLiteral'

エラーの行も表示されるので当該箇所を見たら大体こんな感じ

let str = ~
let array = str.split(separator: "\n") // ← ここでエラー発生
    .map(String.init)

どうやら"\n"(String Literal)がXcode Previews上だとCharacterとして認識されないらしい(なぜ?)

解決策

Characterであることを明示すれば良い。

let array = str.split(separator: "\n" as Character)
// or
let array = str.split(separator: Character("\n"))

参考

https://developer.apple.com/forums/thread/125065

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

Udemyのswiftコース(英語のやつ)でiOSアプリ開発を学ぶ その3

勉強するコースはこれです:point_down:
https://www.udemy.com/course/ios-13-app-development-bootcamp/

進捗

セクション4の途中まで終了(全部で36セクション)
Xcodeの使い方など開発環境について実際の操作を学び、アプリをつくった:grinning:

最初はただ表示するだけのアプリ。二つ目でタップしてサイコロの目を出すアプリを開発する(ようだ)。

感想

前回の記事(Udemyのswiftコース(英語のやつ)でiOSアプリ開発を学ぶ その2)から2週間以上も間があいてしまった…
提出期限とかないしコース視聴いつでもできるし、Angela(先生)の優しさに甘えてしまった(オンラインコースあるある)
やはり絶対にこの曜日のこの時間にやるとか決まり事をつくって習慣化していかないとオンラインコースは続かないのだ(戒め)

何はともあれアプリをつくって自分のiPhoneで表示させるのは実に気分が良い。
エンジニアとしてはちいさな一歩だが、初めて開発をした人にとってはおおきな一歩だとおもう。

コース内の小ネタとしては、スマホアプリ黎明期に「I AM rich.という画面を表示させるだけのアプリで高額課金させて儲けるという詐欺同然の方法で稼いだ人がいた」という話が実に興味深かった。
そのアプリ持っているだけで金持ちの象徴のようなことだしアプリの内容は間違っていない(?)

開発について説明中にちょくちょく小ボケがあったり興味深い話をしたり、飽きない工夫がされているので飽き性の自分でもなんとかできている気がする。

今後の予定

日曜の夜23時頃と水曜の夜23時頃に記事を書くし、書けるようにコースを進める
(習慣化できるように具体的な予定を設定する:point_up:

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

iOS のライブラリを自作して Carthage と CocoaPods で公開する。CI で自動化まで。

こんにちは。iOS エンジニアです。

というふうに名乗っていながら、iOS 向けのライブラリを作ったことがなかったので、やばいと思って作ってみました。
作成中の一連の流れを記事に残したいと思います。
(具体的なコードの書き方とかではないです。)

成果物

https://github.com/yuki0n0/WaveSlider/
以下解説するものは、こちらのライブラリを作成したときの情報に基づいています。

中身自体は大したものではないんですが、
ライブラリ公開の経験をしたかったという動機なのでお手柔らかに、、、
よかったら GitHub で Star ★ つけてね。

作成

1. プロジェクト作成

Framework を選択して、次の画面で選択して、プロジェクト作る。
プロジェクト作成スクリーンショット

2. コーディング

GitHub (もしくは他の git ホスティングサービスなど) にアップしたり、中身を実装したり、自由にやってください。

サンプルプロジェクトの用意

自分のためにも、利用者のためにも、 Example プロジェクトを用意しておくといいかもしれません。
Example フォルダを作成し、その中に通常の iOS アプリの Xcode プロジェクトを作成しているパターンが多いようです。
Example ではなく Demo という名称を使用しているライブラリもありました。

また、その際のライブラリ管理ファイルの書き方は、下記のようにローカルのパスを指定するように記述します。

Podfile
target 'Example' do
  use_frameworks!
  pod "WaveSlider", :path => "../"
end
Cartfile
git "./.."

開発注意ポイント

  • 公開したいクラスなどに public 修飾子をつける
  • Bundle を利用する際は
    Bundle.main... ではなく Bundle(for: WaveSlider.self)... といったように書き換える。
  • etc...

3. 周辺ファイル

README.md

いわずもがな用意しましょう。

LICENSE

LICENSE ファイルを用意しましょう。
CocoaPods でも紹介されている、下記サイトを参考にできます。
https://choosealicense.com/

また、GitHub 上から直接 LICENSE ファイルを作成する場合、
下記のような選択 & 編集画面が出てくるため、わかりやすいです。
GitHub LICENSE 選択

Shared をチェック

Product > Scheme > Manage Schemes... を開いて、
Shared のチェックをつけます。
自分の確認した限りデフォルトでチェックがついていました。
その場合、一度チェックを外してから付け直すといいと思います。

Shared をチェック

公開

バージョニングの前提

セマンティックバージョニング に基づいていれば問題なさそうです。
また、Carthage はセマンティックでも alpha rc などの文字列が続くものはサポートされていません

つまり、バージョン名(=タグ)は下記のような通常のものだけを利用していれば問題ないと思います。
冒頭に v などもつける必要はありません。
1.0.0 1.0.2 ... 1.1.0 ... 2.0.0 ...

CocoaPods

1. podspec を作成

下記コマンドで ライブラリ名.podspec ファイルを生成します。

pod spec create ライブラリ名

作成された下記のようなファイルを、書き換えていきます。
詳細なコメントが書いてあるため、そんなに困らないと思います。
困ったら公式ページを参考にしてもいいと思います。

WaveSlider.podspec
Pod::Spec.new do |spec|
  spec.name         = "WaveSlider"
  spec.version      = "1.0.0"
  ...
end

下記コマンドで確認し、エラーがなくなるまで修正を繰り返し、 git push します。

pod spec lint
# もし問題がなければ下記のような出力が表示されるとお見ます
# [ライブラリ名] passed validation.

2. Release を作成 (タグを付ける)

Release を作成しましょう。
Releaseを作成

3. 登録作業

# 登録
# 確認メールが届くのでリンクを開いて認証する
pod trunk register "メールアドレス" "名前"

# CocoaPods にライブラリの登録
# 場合によっては --allow-warnings オプションを付けてもいいかもしれません
pod trunk push ライブラリ名.podspec

これで終わりです!
こんな感じで作成したライブラリのページが作られていると思います!
https://cocoapods.org/pods/WaveSlider

Carthage

ほぼやることはないです!
基本的に公式ドキュメントもしっかり見れるといいですね。
https://github.com/Carthage/Carthage#supporting-carthage-for-your-framework

1. 確認作業

下記コマンドを実行して問題ないかを確認します。
成功した際 Carthage/Build ディレクトリに成果物ができますが、こちらは git に含める必要はないので .gitignore に追記しておくべきです。

carthage build --no-skip-current

# もし成功しない場合は下記のようなコマンドを実行すると解決の糸口になるかもしれないよ by 公式ドキュメント
xcodebuild -scheme SCHEME -workspace WORKSPACE build
xcodebuild -scheme SCHEME -project PROJECT build

2. Release を作成 (タグを付ける)

CocoaPods の方の手順と同じです。すでにやっているなら必要ないです。
---- ここまでで最低限の公開作業は終わりです! ----

3. バイナリを Release にアップロードしておく (手動)

GitHub の Release には、ファイルをアップロードしておける機能があります。
画像で言う Assets の部分です。
ReleaseのAssets
ここにビルド済みのバイナリをアップロードしておきます。
するとライブラリ利用者側はこのバイナリを利用できるため、ビルド時間を省略できるというメリットがあります。

下記コマンドを実行すると、 *.framework.zip が作成されます。

carthage build --archive

これを下記からアップロードすれば完了です。
Releaseにアップロード

補足

アップロードされているバイナリが「Swiftのバージョンが異なる」等の理由で利用できない場合があります。
その場合は Carthage 側が自動的に判断1して、バイナリは利用せずにソースコードからビルドして利用します。
強制的にバイナリを使用したくない場合は --no-use-binaries オプションを付与してコマンドを実行します。

4. バイナリアップロードを自動化

上記の手動で行った手順を、GitHub Actions で実行します。
トリガーは release が公開されたタイミングとします。
コードは下記から御覧ください。
https://github.com/yuki0n0/WaveSlider/blob/1.0.2/.github/workflows/release_published.yaml

on:
  release:
    types: [published]

jobs:
  ...

Swift Package Manager

Swift Package Manager の対応もしたいですが、時間があるときに気が向いらたらやります。

参考


  1. Carthage 0.20.0 以降 

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