| [[Xcode]] | [[Mac]] | [[IPhone Xcode]] | [[SwiftUI]] | [[Swift Sample]] | [[Cocoa]] | [[リファクタリング]] |
{{amazon|B081GK7636}}
==環境==
=====XCTest=====
*ユニットテスト用
====[https://developer.apple.com/jp/mac-catalyst/ Mac Catalyst]====
*https://developer.apple.com/jp/mac-catalyst/
Mac Catalystを使って構築したMac向けのネイティブAppは、iPad向けAppとコードを共有でき、Mac専用の機能を追加することもできます。macOS Montereyでは、最新のAPIを使用して、ウインドウのタイトルバーにポップアップボタン、ツールチップ、サブタイトルを表示することができます。また、タッチ操作の代替機能、キーボードで操作する機能、SiriのIntentのサポートを提供できるほか、Commandキーを押しながら「P」を押していつでもプリントできるようにするなど、さまざまな操作への対応が追加されました
====[https://www.swift.org/package-manager/ Swift Package Manager]====
----
*https://www.swift.org/package-manager/
*https://blitzgate.co.jp/blog/2234/
*https://qiita.com/hironytic/items/09a4c16857b409c17d2c
=====[https://swiftpackageindex.com/ Swift Package Index]=====
===[[Ubuntu]]へインストール===
----
*オープンソースデバッガ
====Interface Builder====
----
=====[https://www.typea.info/blog/index.php/2022/03/08/xamarin_mac_app_storyboard/ storyboard]=====
*[https://www.typea.info/blog/index.php/2022/03/08/xamarin_mac_app_storyboard/ storyboard]
=====[https://www.typea.info/blog/index.php/2022/03/11/nstableview_celbased/ NSTableView CellBased]=====
*[https://www.typea.info/blog/index.php/2022/03/11/nstableview_celbased/ NSTableView CellBased]
=====[https://www.typea.info/blog/index.php/2022/03/23/nstableview_viewbased_macos/ NSTableView ViewBased]=====
*[https://www.typea.info/blog/index.php/2022/03/23/nstableview_viewbased_macos/ NSTableView ViewBased]
=====[https://www.typea.info/blog/index.php/2022/04/03/nsalert_macos/ NSAlert ダイアログ]=====
*[https://www.typea.info/blog/index.php/2022/04/03/nsalert_macos/ NSAlert ダイアログ]
====AutoLayout====
----
=====[https://www.typea.info/blog/index.php/2022/03/26/autolayout_concept/ AutoLayout概要]=====
*[https://www.typea.info/blog/index.php/2022/03/26/autolayout_concept/ AutoLayout概要]
=====[https://www.typea.info/blog/index.php/2022/03/28/interface_builder_autolayout/ AutoLayout操作]=====
*[https://www.typea.info/blog/index.php/2022/03/28/interface_builder_autolayout/ AutoLayout操作]
=====[https://www.typea.info/blog/index.php/2022/05/30/swift_ios_chart/ AutoLayout簡易操作 TinyConstraint]=====
*[https://www.typea.info/blog/index.php/2022/05/30/swift_ios_chart/ AutoLayout簡易操作 TinyConstraint]
====画面遷移====
----
*https://qiita.com/superman9387/items/c006ced215352f28a7b9
=====[https://www.typea.info/blog/index.php/2022/03/13/storyboard_childwindow_macos/ 子画面表示]=====
*[https://www.typea.info/blog/index.php/2022/03/13/storyboard_childwindow_macos/ storyboard を使って子画面を表示]
=====[https://www.typea.info/blog/index.php/2022/03/15/storyboard_segue_connect_screen/ segue(セグエ)で画面遷移]=====
----
*[https://www.typea.info/blog/index.php/2022/03/15/storyboard_segue_connect_screen/ storyboard segue(セグエ)で画面遷移]
*segueを呼び出し画面遷移させる
<pre>
//呼び出し元
performSegue(withIdentifier: "some_segue_id", sender: nil)
</pre>
=====[https://www.typea.info/blog/index.php/2022/06/04/ios_swift_navigation_controller/ Navigation Controller ナビゲーションバー]=====
*[https://www.typea.info/blog/index.php/2022/06/04/ios_swift_navigation_controller/ NavigationController ナビゲーションバー]
=====[https://www.typea.info/blog/index.php/2022/03/12/interfacebuilder_storyboard_tabview_screentransition/ Tab Viewの利用と画面遷移]=====
*[https://www.typea.info/blog/index.php/2022/03/12/interfacebuilder_storyboard_tabview_screentransition/ storyboard を使って Tab Viewの利用と画面遷移]
==コマンドライン==
=====Float=====
=====Double=====
====型を調べる====
<pre>
1> print(type(of:"hello"))
String
</pre>
===変数の定義===
*リテラルは、"で囲む
*\n 改行など\でエスケープ
====書式====
<pre>
let frmt = String(format: "%03d", 1)
</pre>
====トリミング====
----
====初期化====
----
*Optional<T> は T?で宣言できる: String?*Optional<T> を T! で宣言すると、使用時に自動的にアンラップされる: String!
<pre>
5> let i = Optional(1)
*メモリ上のバイト列を管理
*Foundationのimportが必要
====Stringとの相互変換====
<pre>
let data: Data? = str.data(using: .utf8)
let str: String? = String(data: data, encoding: .utf8)
</pre>
==コレクション==
</pre>
====map関数スライス====*元の配列内の全てのアイテムに対してアクションを行い結果に基づいた配列を作成
<pre>
8> l$R5: [Int] = 8 values { [0] = 1 [1] = 2 [2] = 3 [3] = 4 [4] = 5 [5] = 6 [6] = 7 [7] = 8} 9> l[2..<5]$R6: ArraySlice<Int> = 3 values { [2] = 3 [3] = 4 [4] = 5</pre> ====map関数====*元の配列内の全てのアイテムに対してアクションを行い結果に基づいた配列を作成<pre>let base = [1,2,3]let dbl = base.map {
(val) -> Int in
return val * 2
</pre>
===辞書 [https://developer.apple.com/documentation/swift/dictionary Dictionary<Key, Value>]===
----
*キーと値をもつコレクション
3>
</pre>
*====削除====
<pre>
3> sex.removeValue(forKey:"1")
}
}
</pre>
====空の辞書====
<pre>
var emptyDict: [String: String] = [:]
</pre>
6> f.contains(3.0)
$R0: Bool = true
</pre>
===イテレーター===
[https://developer.apple.com/documentation/swift/iteratorprotocol IteratorProtcol]
<pre>
let animals = ["Antelope", "Butterfly", "Camel", "Dolphin"]
var animalIterator = animals.makeIterator()
while let animal = animalIterator.next() {
print(animal)
}
</pre>
*インクリメント(++)、デクリメント(--) は廃止された
===高度な演算===
----
*Foundation をインポートすることで、sin、logなど利用可能になる
===型の判定===
式 as 型
</pre>
====アップキャスト(as)====----
*as
*コンパイル可能なアップキャストは常に成功
b: String = "abc"
</pre>
====ダウンキャスト(as? as!)====----
*as? キャストが正しく行われた場合オプショナル型、不正な場合、nil
*as! 強制キャスト失敗した場合、実行時エラー
let j= a as! Int
^
</pre>
====独自演算子の定義====
----
*https://qiita.com/shimesaba/items/cb36c0120a0a9f509da7
<pre>
infix operator *** {
associativity none
precedence 130
}
func ***(lhs: Int, rhs: Int) -> Int {
return lhs * rhs
}
</pre>
===repeat-while===
*必ず一回は処理したい場合
<pre>
repeat {
} while 条件
</pre>
===switch===
*break不要
===エラー処理===
----
====Optional<Wrapped>型によるエラー処理====----*値ありを成功、なしを失敗とみなす*エラーが発生する側は、戻り値の型をOptional<Wrapped>とするだけで良い*エラー処理側で、オプショナルチェイン、オプショナルバインディングなど簡潔に記述できる*呼び出し元にエラーの詳細情報を提供できない ====Result<Success,Failure>型によるエラー処理====----*成功を結果の値、失敗を詳細で表す<pre>enum ErrReson : Error { case overflow case even} func someProc(_ underTenOddNum: Int) -> Result<String, ErrReson> { if underTenOddNum >= 10 { return .failure(.overflow) } if underTenOddNum % 2 == 0 { return .failure(.even) } return .success("Success!! odd number & under ten")} func checkResult(_ result: Result<String, ErrReson>) { switch result { case let .success(message): print(message) case let .failure(err): print("\(err)") }} checkResult(someProc(11))checkResult(someProc(8))checkResult(someProc(9))</pre>*結果<pre>overflowevenSuccess!! odd number & under ten</pre< ====エラーを投げる====
----
*プロトコル Errorに適合している必要がある
</pre>
*エラーを投げる関数は直後に、'''throws'''宣言が必要
====エラーハンドリングdo-catchによるエラー処理====
----
*Swift標準のエラー処理機構
*エラーを投げる関数を呼び出すには、関数名の前に'''try'''を付与して呼び出す必要がある
*throw分のエラーを表現するには、エラーであることを表す、Errorプロトコルに準拠する必要がある
*Errorプロトコルに準拠させる場合、列挙を使用するのが一般的
=====tryを使って呼び出すだけ =====
さらに上位に伝播
OVERFLOW
</pre>
====throwsキーワード====
----
*関数、イニシャライザ、クロージャの定義にthrowsを追加すると、それらの中で、do-catchを用いずにthrow文によるエラーを発生させることができる
===guard文===
</pre>
===遅延実行===----*記述されている箇所より後で実行する====defer文====----*スコープを抜ける際に実行したい処理を定義する。*複数のdefer文を記述した場合は逆順で実行される。 ===[https://docs.swift.org/swift-book/ReferenceManual/Patterns.html パターンマッチ]===
----
スコープを抜ける際に実行したい処理を定義する。*値の持つ構造や性質を表現するパターンのマッチングによって制御を行うことができる複数のdefer文を記述した場合は逆順で実行される。*if,guard,for-in,while,doのcatchでも case キーワードを使えば利用できる
<pre>if case パターン = 制御式 {}</pre><pre>guard case パターン = 制御式 else {}</pre>*一致したもののみ処理される<pre>for case パターン in シーケンス {}</pre><pre>while case パターン = 制御式 {}</pre> ====[https://docs.swift.org/swift-book/ReferenceManual/Patterns.html#grammar_expression-pattern 式パターン]====*~= により評価*~= は型別に定義されていて、範囲型では、contains(_:)メソッドで評価される<pre> 19> let n = 3 20> let r = 1...3 21> r ~= n$R4: Bool = true</pre>====[https://docs.swift.org/swift-book/ReferenceManual/Patterns.html バリューバインディングパターン]====*値を変数や定数に代入する*var、let と他のパターンを組み合わせマッチしたら代入<pre> 1> let point = (3, 2) 2> switch point { 3. case let (x, y): 4. print("\(x),\(y)") 5. } 3,2</pre> ====[https://docs.swift.org/swift-book/ReferenceManual/Patterns.html#grammar_optional-pattern オプショナルパターン]====*Optional<T>の値有無を評価<pre> 6> let o: Int? = 42 7> if case .some(let x) = o { 8. print(x) 9. } 42</pre>====[https://docs.swift.org/swift-book/ReferenceManual/Patterns.html#grammar_enum-case-pattern 列挙型ケースパターン]====*列挙型ケースとの一致*列挙型参照 ====is/as演算子によるキャスティングパターン====*is による判定<pre> 12> let a: Any = "s"a: String = "s" 13> switch a { 14. case is String: 15. print("str") 16. default: 17. print("other") 18. } str</pre>*as によるダウンキャスト<pre> 19> let a: Any = 1 20> switch a { 21. case let s as String: 22. print("str:\(s)") 23. case let i as Int: 24. print("int:\(i)") 25. default: 26. print("other") 27. } int:1</pre> ==構造体==*structは値型*プロトコルは、実装すべきメソッドやプロパティが定まっている*構造体の値を変更するメソッドは先頭に mutating を付与
<pre>
struct 名前 : プロトコル{
*初期値のある定数の初期化はできないが、初期値がなければ一度だけ可能
*イニシャライザで構造体のメソッドを利用できるのは、全てのプロパティの初期化が完了してから(メソッドを利用してプロパティの初期値を設定することはできない)
*失敗可能イニシャライザは、init? で定義、失敗した場合、nilを返す
====複数のイニシャライザ====
----
*引数のないイニシャライザ、全項目のイニシャライザは便宜的にコードをかかなくても既定イニシャライザとして、利用できるが、特定のイニシャライザを作成した時点で利用できなくなるので、利用するには別途記述する必要が生じる
==クラス==メンバーワイズイニシャライザ===宣言===
----
*デフォルトで用意されているイニシャライザ
*型が持っているストアドプロパティと同名の引数をとるイニシャライザ
*ストアドプロパティが初期化式と同時に定義されている場合、デフォルト引数となり、呼び出し時に省略できる
<pre>
1> struct Foo { 22. var i: Int 23. var s: String = "" 24. } 25> let f = Foo(i:1, s:"a")f: Foo = { i = 1 s = "a"} 26> let f = Foo(i:2) f: Foo = { i = 2 s = ""}</pre> ==クラス==*self を通してインスタンスにアクセスできる*大文字のSelfで、型自身にアクセスでき、スタティックメソッドなどへのアクセスが容易になる ===宣言===----<pre>class クラス名: スーパークラス, プロトコル {
var 変数: 型 = 初期値
init(引数: 型) {
Yagi 52
</pre>
===継承===
----
<pre>
class クラス名 : スーパークラス名 {
クラス定義
}
</pre>
====オーバーライド====
----
*オーバーライドを行うには、override キーワードを用いて、スーパークラスの要素を再定義する
*super でスーパークラスの実装を呼び出すことができる
*final を記述することで、オーバーライドを禁止できる
*final クラスにすることで、継承を禁止できる
<pre>
class クラス名 : スーパークラス名 {
override func メソッド名 ・・・
override var プロパティ名 ・・・
}
</pre>
===文字列表現===
----
print(meal.foodChoices())
結果:[__lldb_expr_29.FoodChoice.salad, __lldb_expr_29.FoodChoice.sandwich, __lldb_expr_29.FoodChoice.pizza]
</pre>
===連想値===
----
*列挙型では、どのケースかに加え付加情報として連想値を持つことができる
*連想値として持つ型には制限はない
<pre>
enum SomeError : Error {
case notfound(searchkey: String)
case invalidNum(number: Int)
}
let errReason1 = SomeError.notfound(searchkey: "username")
let errReason2 = SomeError.invalidNum(number: 5)
print("\(errReason1)")
print("\(errReason2)")
</pre>
*結果
<pre>
notfound(searchkey: "username")
invalidNum(number: 5)
</pre>
}
</pre>
====引数====
*外部引数名 内部引数名 : 型 と宣言する
*外部引数名を省略したい場合は、 _ を指定する
*デフォルト引数を指定できる
<pre>
import Foundation
==プロパティ==
*構造体、列挙、クラスに定義可能*var、letで定義
===格納型プロパティ===
*定数、変数
1
</pre>
===タイププロパティクラスプロパティ/静的プロパティ===*型に関連class/static を付与*サブクラスで変更される可能性があるかで使い分ける*static を付与継承先で変更される場合、クラスプロパティ*継承先でも同じ値を返す場合、静的プロパティ *クラスプロパティ<pre>class Hoge { class var foo: String { return "foo" }}</pre>
===プロパティオブザーバー===
*プロパティの変更をトリガーに手続きを起動
$ swift subscript.swift
ABC
</pre>
===レイジープロパティ===
*アクセスされるまで初期化を遅延
<pre>
lazy var プロパティ名 : プロパティ型 = 式
</pre>
===KeyPath===
*https://qiita.com/imchino/items/67a987681bca5ad0408b
*「あるデータ型に定義されたプロパティまでの参照(パス)」です。
*キーパス式は、型のプロパティまたは添え字を参照する。
*キー・値監視などの動的プログラミングタスクでは、キーパス式を使用する。
<pre>
\<#type name#>.<#path#>
</pre>
==サブスクリプト==
*コレクションへの統一的なアクセス手法
<pre>
subscript(引数) -> 戻り値の型 {
get {
return 文によって値を返す処理
}
set {
値を更新する処理
}
}
</pre>
*例
<pre>
1> struct Hoge {
2. var children: [Int]
3. subscript(index: Int) -> Int {
4. get {
5. return children[index]
6. }
7. set {
8. children[index] = newValue
9. }
10. }
11. }
12>
13> var hoge = Hoge(children: [1,2,3])
14> print(hoge[2])
3
</pre>
==エクステンション==
*既に存在している型にプロパティやメソッド、イニシャライザなどの構成要素を追加できる
*ストアドプロパティは追加できないが、コンピューテッドプロパティは追加できる
<pre>
extension 定義する対象の型 {
対象に追加したい要素
}
</pre>
*
<pre>
1> extension String {
2. func repeats(times: Int) -> String {
3. var ret = ""
4. for i in 0...times {
5. ret += self
6. }
7. return ret
8. }
9. }
10> let s = "abc"
11> s.repeats(times:3)
$R0: String = "abcabcabcabc"
</pre>
==型のネスト==
*型の中に型を定義できる
<pre>
12> struct Foo {
13. enum Bar {
14. case a
15. case b
16. case c
17. }
18. }
19> let bar = Foo.Bar.b
20> bar
$R1: Foo.Bar = b
</pre>
}
</pre>
===エクステンションによる準拠===
----
*エクステンションでプロトコルに準拠する事も可能
<pre>
extension エクステンションを定義する対象の型 : プロトコル名 {
プロトコルが要求する要素の定義
}
</pre>
===連想型===
----
*プロトコルの準拠時にプロパティ、引数、戻り値の型を指定できる
*連想型の実際の型は準拠する側で指定する
*1つの型に依存しないより抽象的なプロトコルを定義できる
<pre>
protocol プロトコル名 {
associated type 連装型名
var プロパティ名 : 連想型名
func メソッド名(引数名: 連想型名)
func メソッド名() -> 連想型名
}
</pre>
*例
<pre>
protocol Foo {
associatedtype Bar
func info(value: Bar)
}
struct Hoge : Foo {
func info(value: Int) {
print("\(value)")
}
}
let hoge = Hoge()
hoge.info(value:10)
</pre>
===同値、比較===
----
8> r.reduce("", {result, element in result + "-" + String(element) })
$R3: String = "-1-2-3"
</pre>
=====カウントを取る =====
<pre>
let count = sequence.reduce(0) { acc, row in acc + 1 }
</pre>
*firstプロパティ
*lastプロパティ
====変換====
=====Array -> Set =====
<pre>
1> let ary: [Int] = [3,2,3,2]
ary: [Int] = 4 values {
[0] = 3
[1] = 2
[2] = 3
[3] = 2
}
2> print(Set(ary))
[3, 2]
</pre>
===== Set -> Array =====
<pre>
6> let set: Set<Int> = [3,4,5,6]
set: Set<Int> = 4 values {
[0] = 4
[1] = 6
[2] = 3
[3] = 5
}
7> print(Array(set))
[4, 6, 3, 5]
</pre>
==クロージャ==
*基本
*https://qiita.com/atsuastu_jr/items/e3a6990127d96c39a167
<pre>
{ 引数 in 戻り値を返す式 }
hello
</pre>
===関数もクロージャの一つ===
----
*関数もクロージャとして扱える
*関数名を変数に代入
*引数も含めて識別できる
<pre>
1> func Multi(x:Int,y:Int) -> Int {
2. x * y
3. }
4>
5> let m = Multi
6> m(2,3)
$R0: Int = 6
</pre>
===キャプチャリスト===
----
<pre>
hello,swift!
</pre>
===コールバックにクロージャを利用する例===
*非同期処理の結果をクロージャを用いて呼び出し元に返す
<pre>
static func accessRequest(completion:((String?) -> Void)?) {
let allTypes = Set([
HKQuantityType.quantityType(forIdentifier: .bodyMass)!,
/* HKQuantityType.quantityType(forIdentifier: .stepCount)!,*/
])
self.getHealthStore()?.requestAuthorization(toShare: allTypes, read: allTypes) { (success, error) in
if success {
completion?("アクセス許可: \(String(describing: success))")
} else {
completion?("アクセス不許可: \(String(describing: error?.localizedDescription))")
}
}
}
</pre>
</pre>
==並行処理==*https://developer.apple.com/jp/news/?id=2o3euotz===[https://ticklecode.com/swfitgdp/ ディスパッチキュー]例===----*[https://ticklecode Message.com/swfitgdp/ Swiftでの非同期処理GDP|ディスパッチキューの解説|DispatchQueueuser.globalとmain]*[[イベントディスパッチスレッド]]name の重複を取り除き、","で連結して返す
<pre>
Button func joinAndUniqueUserNames(actionmessages: [Message]) -> String { let rootDir var names:Set<String> = EncConverterService.chooseDir()[] // クロージャ例 let queue = DispatchQueue messages.globalforEach(qos: .userInitiated) queue.async { EncConverterServicemessage in names.loadFileinsert(directoryPath: rootDir, filepaths: selfmessage.user.filePathsname)}) } // トレイリングクロージャ例 }) messages.forEach {message in Textnames.insert("Choose dir"message.user.name)
}
return names.joined(separator: ",")
}
</pre>
==[[正規表現]]=属性===*https://www.hackingwithswift.com/example-code/strings/nsregularexpression-how-to-matchSwiftにおけるクロージャには、いくつかの属性を指定できます====@escapeing属性====-regular-expressions-in-strings*https://www.2nd-walkerqiita.com/2020imchino/04/21/swift-how-to-use-nsregularexpressionitems/48564b0c23a64f539060*クロージャは、関数に引数として渡されたとき「関数をエスケープ」できます。*エスケープしたクロージャは、関数に戻った後でも呼び出し可能です。*エスケープクロージャのよくある例として、非同期処理をする完了ハンドラとしてのクロージャがあります。*関数の実行が完了した後にクロージャを呼び出すためには、エスケープしておく必要があります。
<pre>
do { let pattern = #"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"# let regex = try NSRegularExpression func getCurrentTimelineEntry(pattern: pattern, options:[]) for subinput in input.split(separatorcomplication: "\r\n") { let line = String(subinput) let maches = regex.matches(in: line, options: []CLKComplication, rangewithHandler handler: _NSRange@escaping (0..<line.countCLKComplicationTimelineEntry?)-> Void) print(line) for mach in maches { for i in 0 ..< mach.numberOfRanges { // Call the handler with the current timeline entry let start = line.index(line.startIndex, offsetBy: mach.range(at: i).location) let end = line.index(start, offsetBy: mach.range(at: i).length) let text = String(line[start..<end]) print(text) } } }} catch { print handler("RegEx fail."nil) }
</pre>
==ジェネリクス=IsMatch= <pre>func isEquals<T: Equatable> (_ x: T, _ y: T) -> Bool { return x == y}print("\(isEquals("a", "b"))")print("\(isEquals(1.0, 1.0))")</pre>===定義方法===
----
*https://www.hackingwithswift.com/articles/108/how-to-use-regular-expressions-in-swift
<pre>
do func 関数名<型引数> (引数名 : 型引数) -> 戻り値型 { let regex = try NSRegularExpression関数呼び出し実行文}</pre>*例<pre>func genericSample<T, U> (patternx: MATCH_PATTERNT, optionsy:[]U)-> U { return regex.firstMatch(in: stringValue, options: [], range: NSRange(location: 0, lengthlet a : stringValue.utf16.count)) !T = nilx} catch { let b = y print("\(errora),\(b)"); return y
}
print(genericSample(x:1.2, y:"abc"))
</pre>
==[[SwiftUI]]==*[[SwiftUI]]===UIKitとのインターフェースsome,any===*----https://developerjimaru.apple.comblog/tutorialsprogramming/swiftuiswift/interfacingswift-withsome-uikitSwiftUIは既存のApplieプラットフォームUIフレームワークとシームレスに動作する。any/
==[[Mac]]OS並行処理==*https://developer.apple.com/tutorialsjp/swiftuinews/creating-a-macos-app?id=2o3euotz*コアライブラリのFoundationでThreadクラスを提供
==Playground=[https://ticklecode.com/swfitgdp/ ディスパッチキュー]===----*UIスレッド*[https://wwwticklecode.typea.infocom/blogswfitgdp/indexSwiftでの非同期処理GDP|ディスパッチキューの解説|DispatchQueue.phpglobalとmain]*[[イベントディスパッチスレッド]]<pre> Button(action: { let rootDir = EncConverterService.chooseDir() let queue = DispatchQueue.global(qos: .userInitiated) queue.async { EncConverterService.loadFile(directoryPath: rootDir, filepaths: self.filePaths) } }) { Text("Choose dir") }</2020/12/06/xcode_macos_proguramming/ Playground]pre>===値の変化をグラフで見る=Grand Central Dispatch====[[File----*GCDのキューはディスパッチキュー、以下の2種**直列ディスパッチキュー(serial dispatch queue)**並列ディスパッチキュー(concurrent dispatch queue)*利用するには既存のディスパッチキューを取得するか新規に生成*GCDは1つのメインキュート複数のグローバルキューを提供*メインキューはメインスレッドでタスクを実行する直列ディスパッチキュー*iOS/macOSでは、UIの更新は常にメインキューから行われる*取得したディスパッチキューにタスクを追加するには、DispatchQueue.async(execute:Playground_view_result.png|600px]]) メソッドを用いる*<pre>import Foundationimport Dispatch
let mq ===チュートリアル===*https:DispatchQueue.main //developerメインディスパッチキューを取得let gq = DispatchQueue.appleglobal(qos: .comuserInitiated) /tutorials/swiftui/グローバルキューを取得let cq = DispatchQueue(*[https label://www"info.typea.info/blog/indexhoge.queue", qos: .php/2020/12/09/swiftui_tutorial_youtube_memo/ Canvasdefault,TextView]* attributes: [https:.concurrent]) //wwwinfo.typea.info/blog/indexhoge.phpqueue という名前の並列ディスパッチキューを生成</2020/12/19/swiftui_tutorial_custom_image_view/ Custom Image View]pre>====Operation,OperationQueue====----*Operationは実行タスクと情報をカプセル化したものOperationQueueがキューの役割
==Objective-Cの動作モデルとセレクタ==Mainスレッドで実行====*Apple製品はObjective-Cの動作モデルに基づいている---*オブジェクトがプログラムを構成しオブジェクトが相互にメッセージを送信し合うことで動作するUIスレッド<pre> DispatchQueue.main.async { self.hogeLabel.text = result }</pre> ==ユニットテスト=====非同期処理をテストする===<pre>func testAccessRequest() { var result : String? let expectation = expectation(description: "非同期待ち") // 非同期処理の呼び出しとコールバック HealthKitHelper.accessRequest() { accessResult in result = accessResult*このモデルではメッセージの送り先について詳しく知る必要がないため、組み合わせの自由度が高い expectation.fulfill() // 非同期待ち解除*Objective-Cでは、メッセージ送信の際、'''セレクタ'''と呼ばれるデータを使ってメソッドを指定し動的な起動を可能としている }*SwiftではSelector型が提供されており、Selector型でメソッドを呼び出す仕組みは、Objective-CのNSObjectで定義されている *Selector型は構造体だが、'''#selector'''という特殊なイニシャライザを使用する waitForExpectations(timeout: 4) // 指定時間応答がなければ失敗
print("ACCESS REQUEST : \(String(describing: result))") assert(result !==Swift Package Manager==nil) }*[https://swift.org/package-manager</ Swift Package Manager]pre>
==Tips[[正規表現]]=====print改行させない===*https://www.hackingwithswift.com/example-code/strings/nsregularexpression-how-to-match-regular-expressions-in-strings*https://www.2nd-walker.com/2020/04/21/swift-how-to-use-nsregularexpression/
<pre>
do { let pattern = #"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"# let regex = try NSRegularExpression(pattern: pattern, options:[]) for subinput in input.split(separator: "\r\n") { let line = String(subinput) let maches = regex.matches(in: line, options: [], range: _NSRange(0..<line.count)) print(valueline) for mach in maches { for i in 0 ..< mach.numberOfRanges { let start = line.index(line.startIndex, offsetBy: mach.range(at: i).location) let end = line.index(start, terminatoroffsetBy: mach.range(at: i).length) let text = String(line[start..<end]) print(text) } } }} catch { print("RegEx fail.")}
</pre>
===IsMatch===
----
*https://www.hackingwithswift.com/articles/108/how-to-use-regular-expressions-in-swift
<pre>
do {
let regex = try NSRegularExpression(pattern: MATCH_PATTERN, options:[])
return regex.firstMatch(in: stringValue, options: [], range: NSRange(location: 0, length: stringValue.utf16.count)) != nil
} catch {
print("\(error)");
}
</pre>
==[[SwiftUI]]==
*[[SwiftUI]]
===UIKitとのインターフェース===
*https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit
SwiftUIは既存のApplieプラットフォームUIフレームワークとシームレスに動作する。
==[[Mac]]OS==
*https://developer.apple.com/tutorials/swiftui/creating-a-macos-app
==Playground==
*[https://www.typea.info/blog/index.php/2020/12/06/xcode_macos_proguramming/ Playground]
===値の変化をグラフで見る===
[[File:Playground_view_result.png|600px]]
===チュートリアル===
*https://developer.apple.com/tutorials/swiftui/
*[https://www.typea.info/blog/index.php/2020/12/09/swiftui_tutorial_youtube_memo/ Canvas,TextView]
*[https://www.typea.info/blog/index.php/2020/12/19/swiftui_tutorial_custom_image_view/ Custom Image View]
==Objective-Cの動作モデルとセレクタ==
*Apple製品はObjective-Cの動作モデルに基づいている
*オブジェクトがプログラムを構成しオブジェクトが相互にメッセージを送信し合うことで動作する
*このモデルではメッセージの送り先について詳しく知る必要がないため、組み合わせの自由度が高い
*Objective-Cでは、メッセージ送信の際、'''セレクタ'''と呼ばれるデータを使ってメソッドを指定し動的な起動を可能としている
*SwiftではSelector型が提供されており、Selector型でメソッドを呼び出す仕組みは、Objective-CのNSObjectで定義されている
*Selector型は構造体だが、'''#selector'''という特殊なイニシャライザを使用する
==Swift Package Manager==
*[https://swift.org/package-manager/ Swift Package Manager]
==Storyboard==
===[https://www.typea.info/blog/index.php/2022/03/08/xamarin_mac_app_storyboard/ Storyboard]===
===[https://www.typea.info/blog/index.php/2022/03/11/nstableview_celbased/ Table View]===
===[https://www.typea.info/blog/index.php/2022/03/12/interfacebuilder_storyboard_tabview_screentransition/ Tab View画面遷移]===
==Tips==
====watchOS====
=====[https://www.typea.info/blog/index.php/2022/06/04/ios_watchos_dev_env/ watchOS を iOS プロジェクトに統合]=====
=====[https://www.typea.info/blog/index.php/2022/06/07/watchos_app_prestudy/ watchOS 開発概要]=====
----
[https://developer.apple.com/documentation/watchos-apps Developer Document]
=====[https://www.typea.info/blog/index.php/2022/06/08/swift_watchos_simple_app_connect_healthkit/ HealthKit利用 watchOS アプリ作成]=====
=====[https://www.typea.info/blog/index.php/2022/06/11/swift_watchos_complication_watchface_run_app/ コンプリケーションを文字盤に追加する]=====
=====[https://www.typea.info/blog/index.php/2022/06/14/swift_watchos_watchface_complication/ 文字盤に画像や情報を表示する]=====
=====[https://developer.apple.com/documentation/watchos-apps/setting-up-tests-for-your-watchos-app Unit Tests]=====
=====[https://qiita.com/am10/items/e58dfe28f024b3dc39ad WatchKitオブジェクト]=====
====HealthKit====
=====[https://www.typea.info/blog/index.php/2022/05/31/ios_swift_healthkit/ iOS SwiftにHealthKitを組み込む]=====
=====[https://www.typea.info/blog/index.php/2022/06/04/swift_ios_healthkit_healthdata/ ヘルスデータを読む]=====
=====[https://www.typea.info/blog/index.php/2022/06/09/swift_watchos_save_healthdata/ ヘルスデータを書き込む]=====
====チャート====
[https://www.typea.info/blog/index.php/2022/05/30/swift_ios_chart/ iOS Swiftにチャートを組み込む]
====[[Sqlite]]====
[https://www.typea.info/blog/index.php/2022/05/19/ios_swift_sqlite_via_typesafe_wapper/ iOS SwiftでSQLite使用する]
====ランダム====
<pre>
2> Int.random(in:1 ... 9999)
$R1: Int = 8549
</pre>
====Sum/Average====
<pre>
1> let l = [1,2,3,4,5]
l: [Int] = 5 values {
[0] = 1
[1] = 2
[2] = 3
[3] = 4
[4] = 5
}
2> l.reduce(0,+)
$R0: Int = 15
3> l.reduce(0,+) / l.count
$R1: Int = 3
</pre>
====[[デザイン]]====
=====[https://photoshopvip.net/102903 配色]=====
*http://photoshopvip.net/95427
*https://colorhunt.co/palette/196224
=====アイコン=====
*https://www.flaticon.com
====書式====
=====カンマつき数値=====
<pre>
2> import Foundation
3> let nfmt = NumberFormatter()
4> nfmt.numberStyle = .decimal
5> print(nfmt.string(from: NSNumber(value:12345)))
Optional("12,345")
</pre>
=====小数点桁揃え=====
<pre>
print(String(format:"%.1f", (5.0 / 3.0)))
1.7
</pre>
=====桁揃え=====
<pre>
print(String(format:"%05d", 99))
00099
</pre>
===日付===
====書式====
<pre>
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter.string(from: day)
</pre>
====曜日判定====
<pre>
let calendar = Calendar(identifier: .gregorian)
return calendar.component(.weekday, from: date)
</pre>
====日付計算====
<pre>
3> let today = Date()
today: Foundation.Date = 2022-06-18 02:38:05 UTC
4> let tommorow = Calendar.current.date(byAdding: .day, value:1, to: today)
tommorow: Foundation.Date? = 2022-06-19 02:38:05 UTC
</pre>
*NSDateに変換
<pre>
2> let d = Calendar.current.date(byAdding: .month, value:1, to: Date()) as! NSDate
d: NSDate = 2022-07-03 15:38:43 UTC
</pre>
===[[JSON]]===
[[Swift Sample]]
===print改行させない===
----
<pre>
print(value, terminator: "")
</pre>
===ファイルを読む===
----