- 投稿日:2020-08-06T21:59:14+09:00
[XCode 11.6, Swift5.2.4] プログラム初心者の「コピペ前は動いていたのに!」
著者とプログラム環境は現在以下になります。
- 本格的なプログラミングは初めて(昔HyperCardでチマチマ作ったことはある)
- 各種アプリのマクロは理解できる程度
- Swift歴は4ヶ月くらい、SwiftUI歴は1ヶ月くらい
- Xcode 11.6
- Swift5.2.4
コピペで動くと思っている初心者
それは私です。
動いているコードをコピペして、XCodeから怒られた事例を見ていきます。
もしこのドキュメントが、読者の何らかの助けになっていれば幸いです。説明用にSwiftUIのコードを用意しました。
ファイル作成時に、以下の変更を加えたものになります。
1. Text("Hello, World")を作成しました。
2. 間の部分の説明を追加しました。import SwiftUI //(この部分を、Aと呼ぶ) struct SwiftUIView: View { //(この部分を、Bと呼ぶ) var body: some View { Text("Hello, World!") //(この部分を、Cと呼ぶ) } //(この部分を、Bと呼ぶ) } //(この部分を、Aと呼ぶ) struct SwiftUIView_Previews: PreviewProvider { //(この部分を、Bと呼ぶ) static var previews: some View { SwiftUIView() //(この部分を、Cと呼ぶ) } } //(この部分を、Aと呼ぶ)import SwiftUI部分
- 怒られた点
- import Foundationのファイルで、enumや Array[Type]を置いていたが、Color型を使った瞬間怒られた。
- 解っていなかった点
- Color型を使うにはimport SwiftUIが必要だった。FoundationはColor型を使えない。
A部分
- 特になし。なぜなら使ったことないから。
- import Foundationのファイルでは、A部分にenumやArray[Type]を書いていたので、ここに書くと他のファイルでも変数が使えると思う(グローバル変数?)。
- 変数が散り散りになるので、普通のSwiftUIでA部分は使わない方がいい。
B部分・C部分
ここはBとCで結局同じ原因で怒られているので、まとめて書きます。
- B部分:怒られた点
- ForEachを使うと怒られた。
- Text()を使うと怒られた。
- C部分で使えた文をコピペすると、変数が使えなくて怒られた。
- C部分:怒られた点
- for in ループを使うと怒られた。
- if elseやswitch caseを使うと怒られた。ただしreturnを使うと大丈夫(Group{}で囲ってもいい)。
- varを定義したら怒られた。@State varも同様。
- selfをやたら勧められる
- 解っていなかった点
- B部分は構造体Structの中、C部分は変数var body: some viewの中にあるということ。
- C部分はvarの中なので、新たにvarを定義することはできない。
- B部分はStruct直下なのでvarを定義できる。
- C部分のコードはViewを返さないといけない(some view)。
- C部分ではViewを返すコードを繰り返すことができるForEachを使う。
- var内でif elseを使うと考えると、それは無理でしょうと(個人的には)思う。
- なので、C部分のif else内ではreturnを使って、Viewを返す(Group{}で囲っても良い)。
- B部分で定義した変数を、C部分で扱うときにはselfをつける。
- Cから見ると、自分が所属しているStructの変数を使うので、selfを使う。
initialize で怒られる(コードに問題ないのにbuildできない)
正直、原因はいろいろありますが、コードは問題ない(と思われる)のに、どうしてもbuildできない時は、Previewsから値が渡されていないのかもしれません。
- 条件(上記コードを例とします)
- B部分で、@State var hogehoge: <型>を使用しており、=で値を入れていない。
- 他のファイルで、SwiftUIView(hogehoge: fugafuga)と変数渡しする必要がある。
- 原因
- SwiftUIView_Previewsから、SwiftUIView()に変数hogehogeの値を渡していない。
- 方法
- SwiftUIView_PreviewsのB部分で、fugafugaを作る。let fugafuga = xxxなど。
- swiftUIView_PreviewsのC部分で、SwiftUIView (hogehoge: fugafuga)とする
Previewsはそのページのコードの結果だけ、作って見せてくれる。 そのため、他のページからの変数渡しやCoreDataなどとの連携はできない。
Previewsでは渡される値を作って(上記letの部分)、渡しておく必要がある。
これを忘れていると、コード的には問題ないのにinitializeで怒られてしまい、buildができないことになる。
- 投稿日:2020-08-06T20:15:08+09:00
Xcode の Swift Package : Unit テストのメソッド名の先頭は "test" 縛り
- 投稿日:2020-08-06T19:07:31+09:00
SwiftでGoogleのMaterialDesignを簡単に使ってみる
今回使うライブラリ
今回使うのは、GoogleがデザインしたMaterialDesignです。
iOS(Swift,Objective-C)だけでなく、Android(Java,Kotolin),Web(HTML,CSS,JavaScript?)もあります。
(詳しくはこちら)
パーツは material.io/components から探せるので、気に入ったものを探してみてください。
その中でも今回はTextFieldを使いたいと思います。注意書き
今回はあくまで簡単(機能する程度)に実装するだけですので、Usageに書かれていることとは違うと思いますが、しっかりゴリゴリに実装したい方は、この記事を読まずにUsageを熟読することをおすすめします。
※こんな感じで少し雑な記事になると思いますがお許しください。。。Podライブラリ導入
・Podファイルの生成
$ pod init・Podファイルに追加
pod 'MaterialComponents/TextFields'・Podインストール
$ pod install使い方
・
.workspace
ファイルを開きます。・ストーリーボードに普通のUITextFieldを配置します。
・
ViewController.swift
にMaterialComponents.MaterialTextFieldsをインポートします。ViewController.swiftimport MaterialComponents.MaterialTextFields・先ほどStoryboardに配置したUITextFieldとコードを関連付けをします。
ViewController.swift@IBOutlet weak var GoogleTextField: UITextField!・Storyboardに戻り、TextFieldのカスタムクラスを、
MDCTextField
に変更します。
・背景にこんな感じの入力する項目みたいなのをつけたいという方は・・・
サンプルGIF
サンプルプロジェクト
- 投稿日:2020-08-06T18:42:04+09:00
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)) }
- 投稿日:2020-08-06T15:26:28+09:00
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)とも呼ばれる。
.
フツーの配列は、インデックス(=始点からのズレ。) で、値を特定。
連想配列では、キーによって、値を特定。まとめ休憩?
-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で、「キーの入力待ち」 的な感じで、
forKey
の for は、接続詞だと思ふ。おわりに
PlayGround、シンプルで秀逸。
参考サイト
- 投稿日:2020-08-06T14:03:24+09:00
RealmSwiftのMigration
個人での開発中に、モデル定義を変更したところ、マイグレーションしてくれというエラーが出たため、備忘録として残しておきます。
マイグレーションとは
モデルの定義を変更したときに、データを保持したまま新しいモデル定義に適応させることをいいます。
サンプル
エラー
Realm公式に載っているコードで説明します。
すでに定義されている下記のモデルを変更してみます。class Person: Object { @objc dynamic var firstName = "" @objc dynamic var lastName = "" @objc dynamic var age = 0 }以下のように変更しました。
class Person: Object { @objc dynamic var firstName = "" //ここを消しました @objc dynamic var age = 0 }マイグレーションの設定を行わず、これでシュミレーターを起動すると、下記のようなエラーが出て、うまく起動しません。
Error Domain=io.realm Code=10 "Migration is required due to the following errors:
(エラー文以下省略)解決策
AppDelegate.swiftのdidFinishLaunchingWithOptionsの部分で、マイグレーションに関する記述をしていきます。公式のコードを参照。
AppDelegate.swift// Inside your application(application:didFinishLaunchingWithOptions:) let config = Realm.Configuration( // Set the new schema version. This must be greater than the previously used // version (if you've never set a schema version before, the version is 0). //(訳)新しいスキーマのバージョンを設定。以前使っていたバージョンよりも高くなければいけない。これまでバージョンの設定をしていなければ、初期のバージョンの値は0。 schemaVersion: 1, // Set the block which will be called automatically when opening a Realm with // a schema version lower than the one set above //(訳)上記のものより低いスキーマバージョンでrealmを開くときに、自動的に呼び出されるようにブロックの設定をする。 migrationBlock: { migration, oldSchemaVersion in // We haven’t migrated anything yet, so oldSchemaVersion == 0 //(訳)まだマイグレーションを行っていないので、oldSchemaVersion == 0。 if (oldSchemaVersion < 1) { // Nothing to do! // Realm will automatically detect new properties and removed properties // And will update the schema on disk automatically //(訳)Realmは新しいプロパティと削除されたプロパティを自動で検知します。そして、自動でディスク上のスキーマを更新する。 } }) // Tell Realm to use this new configuration object for the default Realm //(訳)default Realmに対して、新しい設定オブジェクトを使うように、Realmに指示する。 Realm.Configuration.defaultConfiguration = config // Now that we've told Realm how to handle the schema change, opening the file // will automatically perform the migration let realm = try! Realm()最低限、スキーマがRealmによって(自動的に)アップグレードされたことを示すために、空のブロックでバージョンを更新する必要がある。
まとめ
自分は、開発の環境で、モデルの変更を行ったらschemaVersionを変更してあげています。
間違えているところがあれば、ご指摘いただけますと幸いです。
- 投稿日:2020-08-06T12:19:56+09:00
[swift5]エラーUse of unresolved identifier 'FirebaseApp'の対処法
エラー内容
FacebookログインをFirebaseを用いて実装しようと思い、コードを書いている際に発生したエラーです。記述コードは以下の通り。
AppDelegate.swiftimport 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初学者が高確率で遭遇するエラーだと思われます。
是非参考にして下さい!
- 投稿日:2020-08-06T11:33:28+09:00
iOS14での写真アプリへのアクセスについて
はじめに
※ 本記事はWWDC2020で発表された内容を元に作成しております。
※ 記事中の画像はWWDC2020での発表のものを引用させていただいております。iOS14から写真アプリへのアクセス方法に更新があるため、今回調査してまとめてみました。
写真アプリへのアクセスレベルの指定
iOS14から写真アプリへの認証を確認する際にはアクセスレベルを指定することが必要になります。
これには新たに定義された列挙型のPHAccessLevel
を用います。
これによりアクセスレベルを追加のみ.addOnly
、もしくは読み込み/書き込み.readWrite
に指定することができるようになりました。見た目の変化
iOS13以前では新規でアプリをリリースしてそのアプリ内で写真を撮った場合、単に写真アプリへのアクセスを許可するかどうかの表示となっていたと思います。
iOS14ではアクセスのレベルがより細かく設定できるようになりました。
これにより、写真の追加のみ ├ 許可する └ 許可しない 読み込み/書き込み ├ 全ての写真を対象 ├ 選択した写真のみ対象 └ 許可しないといった選択肢になりました。
PHAccessLevel
を.addOnly
にしていると左画像、.readWrite
にしていると右画像のようになります。
コードでの対応
iOS13までは
PHPhotoLibrary.authorizationStatus()
に引数はありませんでしたが、iOS14では下記コードの中段のように引数にアクセスレベルを宣言する必要があります。
まとめ
iOS14からは
PHAccessLevel
の登場により写真アプリのアクセスに影響が現れるので、アプリの用途に応じて認証の.addOnly
か.readWrite
を宣言する必要があります。
抜け漏れをせずに対応していきましょう。参考
- 投稿日:2020-08-06T11:33:28+09:00
iOS14での写真アプリへのアクセスレベルについて
はじめに
※ 本記事はWWDC2020で発表された内容を元に作成しております。
※ 記事中の画像はWWDC2020での発表のものを引用させていただいております。iOS14から写真アプリへのアクセス方法に更新があるため、今回調査してまとめてみました。
写真アプリへのアクセスレベルの指定
iOS14から写真アプリへの認証を確認する際にはアクセスレベルを指定することが必要になります。
これには新たに定義された列挙型のPHAccessLevel
を用います。
これによりアクセスレベルを追加のみ.addOnly
、もしくは読み込み/書き込み.readWrite
に指定することができるようになりました。見た目の変化
iOS13以前では新規でアプリをリリースしてそのアプリ内で写真を撮った場合、単に写真アプリへのアクセスを許可するかどうかの表示となっていたと思います。
iOS14ではアクセスのレベルがより細かく設定できるようになりました。
これにより、写真の追加のみ ├ 許可する └ 許可しない 読み込み/書き込み ├ 全ての写真を対象 ├ 選択した写真のみ対象 └ 許可しないといった選択肢になりました。
PHAccessLevel
を.addOnly
にしていると左画像、.readWrite
にしていると右画像のようになります。
コードでの対応
iOS13までは
PHPhotoLibrary.authorizationStatus()
に引数はありませんでしたが、iOS14では下記コードの中段のように引数にアクセスレベルを宣言する必要があります。
まとめ
iOS14からは
PHAccessLevel
の登場により写真アプリのアクセスに影響が現れるので、アプリの用途に応じて認証の.addOnly
か.readWrite
を宣言する必要があります。
抜け漏れをせずに対応していきましょう。参考
- 投稿日:2020-08-06T11:24:55+09:00
Swiftのstatic (初歩的)
この記事はstaticの使い方を簡単にまとめたもので、詳しい解説は明記されていません。
使い方
struct MyStructuer { let instanceProperty = "ABC" static let typeProperty = 123 //これだけ!! }変数などを定義する際に、直前にstaticをつけるだけです。
staticをつけた場合と、つけなかった場合の違いを見ていくと
struct MyStructuer { let instanceProperty = "ABC" static let typeProperty = 123 } mystructuer = MyStructuer() //インスタンスを生成 print(mystructuer.instanceProperty) //=> ABC print(MyStructuer.typeProperty) //=> 123どこが違うかというと、
staticをつけていない変数はMyStructuerクラスからインスタンスを生成し、そのインスタンスからプロパティを出力しています。
staticをつけている変数は、インスタンスは使わずにプロパティを出力しています。これによってインスタンスを生成する手間が省け、どこからでも簡単にプロパティを呼び出すことができます。
しかし逆の操作はともにエラーになりますので注意してください。
print(MyStructuer.instanceProperty) //=> エラー print(mystrctuer.typeProperty) //=> エラーstaticはクラスやメソッドにも同様にして使えるので、より快適なコードを目指して使いこなしたいですね!
- 投稿日:2020-08-06T09:19:04+09:00
Stack Viewは便利ですね?
Stack Viewは便利ですね。
Swiftを始めて、3日目。
Stackについて学んだので、簡単にまとめ。-【Swift】超便利StackViewの実践的使い方!まだAutoLayoutで消耗してるの?
-遅ればせながら UIStackView 入門と言っても、他サイト引用です。?
-Stack
「レイアウトの修正が大変...」という
Auto Layout
の欠点を解決してくれます。
最低限のAutoLayout
の設定で済む、良心的な機能です。補足
右下に5個並んでるボタンについて、ちょっと補足。
-Stackの削除
Embed In
(一番右) にて、Unembed-Constraintの更新・削除
Resolve Auto Layout Issues
(右から2番目) にて、
Update~ が更新。
Clear~ が削除。Updateすると、上記画像のオレンジ色の「所定のConstraintからズレてるよ!」的な
警告が消える。-元のConstraintの位置に戻す
Update Frames
(一番左)
(名称が "Return Frames" じゃない理由が謎。?)※使用環境
iOS8以前では、Stack View は使用できないみたいです。
iOS9以上で利用可能。おまけ
View Controller
の召喚。
オブジェクトライブラリで、View Controllerと検索。
Is Initial View Controller
のチェックを忘れずに。
Runしたときの、EntryPoint になります。(最初に始まる画面になる。)※当たり前ですが、EntryPointの複数指定は無理なので、
他のView Controllerでのチェックは自動で消えてくれます?オブジェクトライブラリ表示。
-Command + shift + L
(Option長押し、表示を維持)
(一回ドラッグ&ドロップすれば、あとは長押し続けなくても表示を維持)終わりに。
ネイティブアプリ開発は、エミュレーターが楽しい。
PC画面上にスマホがあるという感動 ?
- 投稿日:2020-08-06T02:50:19+09:00
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"))参考
- 投稿日:2020-08-06T02:43:59+09:00
Udemyのswiftコース(英語のやつ)でiOSアプリ開発を学ぶ その3
勉強するコースはこれです
https://www.udemy.com/course/ios-13-app-development-bootcamp/進捗
セクション4の途中まで終了(全部で36セクション)
Xcodeの使い方など開発環境について実際の操作を学び、アプリをつくった最初はただ表示するだけのアプリ。二つ目でタップしてサイコロの目を出すアプリを開発する(ようだ)。
感想
前回の記事(Udemyのswiftコース(英語のやつ)でiOSアプリ開発を学ぶ その2)から2週間以上も間があいてしまった…
提出期限とかないしコース視聴いつでもできるし、Angela(先生)の優しさに甘えてしまった(オンラインコースあるある)
やはり絶対にこの曜日のこの時間にやるとか決まり事をつくって習慣化していかないとオンラインコースは続かないのだ(戒め)何はともあれアプリをつくって自分のiPhoneで表示させるのは実に気分が良い。
エンジニアとしてはちいさな一歩だが、初めて開発をした人にとってはおおきな一歩だとおもう。コース内の小ネタとしては、スマホアプリ黎明期に「I AM rich.という画面を表示させるだけのアプリで高額課金させて儲けるという詐欺同然の方法で稼いだ人がいた」という話が実に興味深かった。
そのアプリ持っているだけで金持ちの象徴のようなことだしアプリの内容は間違っていない(?)開発について説明中にちょくちょく小ボケがあったり興味深い話をしたり、飽きない工夫がされているので飽き性の自分でもなんとかできている気がする。
今後の予定
日曜の夜23時頃と水曜の夜23時頃に記事を書くし、書けるようにコースを進める
(習慣化できるように具体的な予定を設定する)
- 投稿日:2020-08-06T02:27:31+09:00
iOS のライブラリを自作して Carthage と CocoaPods で公開する。CI で自動化まで。
こんにちは。iOS エンジニアです。
というふうに名乗っていながら、iOS 向けのライブラリを作ったことがなかったので、やばいと思って作ってみました。
作成中の一連の流れを記事に残したいと思います。
(具体的なコードの書き方とかではないです。)成果物
https://github.com/yuki0n0/WaveSlider/
以下解説するものは、こちらのライブラリを作成したときの情報に基づいています。中身自体は大したものではないんですが、
ライブラリ公開の経験をしたかったという動機なのでお手柔らかに、、、
よかったら GitHub で Star ★ つけてね。作成
1. プロジェクト作成
Framework を選択して、次の画面で選択して、プロジェクト作る。
2. コーディング
GitHub (もしくは他の git ホスティングサービスなど) にアップしたり、中身を実装したり、自由にやってください。
サンプルプロジェクトの用意
自分のためにも、利用者のためにも、 Example プロジェクトを用意しておくといいかもしれません。
Example フォルダを作成し、その中に通常の iOS アプリの Xcode プロジェクトを作成しているパターンが多いようです。
Example ではなく Demo という名称を使用しているライブラリもありました。また、その際のライブラリ管理ファイルの書き方は、下記のようにローカルのパスを指定するように記述します。
Podfiletarget 'Example' do use_frameworks! pod "WaveSlider", :path => "../" endCartfilegit "./.."開発注意ポイント
- 公開したいクラスなどに
public
修飾子をつける- Bundle を利用する際は
Bundle.main...
ではなくBundle(for: WaveSlider.self)...
といったように書き換える。- etc...
3. 周辺ファイル
README.md
いわずもがな用意しましょう。
LICENSE
LICENSE
ファイルを用意しましょう。
CocoaPods でも紹介されている、下記サイトを参考にできます。
https://choosealicense.com/また、GitHub 上から直接
LICENSE
ファイルを作成する場合、
下記のような選択 & 編集画面が出てくるため、わかりやすいです。
Shared をチェック
Product > Scheme > Manage Schemes...
を開いて、
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.podspecPod::Spec.new do |spec| spec.name = "WaveSlider" spec.version = "1.0.0" ... end下記コマンドで確認し、エラーがなくなるまで修正を繰り返し、 git push します。
pod spec lint # もし問題がなければ下記のような出力が表示されるとお見ます # [ライブラリ名] passed validation.2. Release を作成 (タグを付ける)
3. 登録作業
# 登録 # 確認メールが届くのでリンクを開いて認証する pod trunk register "メールアドレス" "名前" # CocoaPods にライブラリの登録 # 場合によっては --allow-warnings オプションを付けてもいいかもしれません pod trunk push ライブラリ名.podspecこれで終わりです!
こんな感じで作成したライブラリのページが作られていると思います!
https://cocoapods.org/pods/WaveSliderCarthage
ほぼやることはないです!
基本的に公式ドキュメントもしっかり見れるといいですね。
https://github.com/Carthage/Carthage#supporting-carthage-for-your-framework1. 確認作業
下記コマンドを実行して問題ないかを確認します。
成功した際Carthage/Build
ディレクトリに成果物ができますが、こちらは git に含める必要はないので.gitignore
に追記しておくべきです。carthage build --no-skip-current # もし成功しない場合は下記のようなコマンドを実行すると解決の糸口になるかもしれないよ by 公式ドキュメント xcodebuild -scheme SCHEME -workspace WORKSPACE build xcodebuild -scheme SCHEME -project PROJECT build2. Release を作成 (タグを付ける)
CocoaPods の方の手順と同じです。すでにやっているなら必要ないです。
---- ここまでで最低限の公開作業は終わりです! ----3. バイナリを Release にアップロードしておく (手動)
GitHub の Release には、ファイルをアップロードしておける機能があります。
画像で言う Assets の部分です。
ここにビルド済みのバイナリをアップロードしておきます。
するとライブラリ利用者側はこのバイナリを利用できるため、ビルド時間を省略できるというメリットがあります。下記コマンドを実行すると、
*.framework.zip
が作成されます。carthage build --archive
補足
アップロードされているバイナリが「Swiftのバージョンが異なる」等の理由で利用できない場合があります。
その場合は Carthage 側が自動的に判断1して、バイナリは利用せずにソースコードからビルドして利用します。
強制的にバイナリを使用したくない場合は--no-use-binaries
オプションを付与してコマンドを実行します。4. バイナリアップロードを自動化
上記の手動で行った手順を、GitHub Actions で実行します。
トリガーは release が公開されたタイミングとします。
コードは下記から御覧ください。
https://github.com/yuki0n0/WaveSlider/blob/1.0.2/.github/workflows/release_published.yamlon: release: types: [published] jobs: ...Swift Package Manager
Swift Package Manager の対応もしたいですが、時間があるときに気が向いらたらやります。
参考
- iOSライブラリの自作とcarthage公開
https://gist.github.com/sahara-ooga/18820c55cc8591694fa7aba651625908- How to get just the tag name? - GitHub Actions - GitHub Support Community
https://github.community/t/how-to-get-just-the-tag-name/16241/21- GitHub Actions で 自作Cocoapodsライブラリを自動デプロイする
https://qiita.com/ry-itto/items/0fab3fdc4321bfbd3877- What's the difference between 'pod spec lint' and 'pod lib lint'?
https://stackoverflow.com/a/32328089- Carthageの配布の仕方(すっごい簡単!)
https://qiita.com/morizotter/items/56658ed7920059beaa8e- 自作ライブラリのCocoaPods対応
https://qiita.com/am10/items/9097dd87c4eaa6ec5350- Carthgeで事前にビルドしたバイナリファイルを提供するには
https://teratail.com/questions/22246- vsouza/awesome-ios
https://github.com/vsouza/awesome-ios
Carthage 0.20.0 以降 ↩