回答編集履歴
2
エラーについてのコメントを追記しました。
test
CHANGED
@@ -84,3 +84,27 @@
|
|
84
84
|
> messageStringにurlを代入するのでしょうか?
|
85
85
|
messageStringに欲しい結果(URL)が格納されていますので、それを使って何か必要な処理を書いてみてください。
|
86
86
|
|
87
|
+
### 追記2です。
|
88
|
+
|
89
|
+
コメントありがとうございます。
|
90
|
+
|
91
|
+
> 戻り値の型をstringで指定して返そうとすると、
|
92
|
+
> このエラーが、関数を呼び出す部分で発生します。
|
93
|
+
> voidに変換できないとのことですが、そもそもvoid型はデータ型不明というような型ではないのでしょうか?
|
94
|
+
|
95
|
+
Voidはメソッド(関数)の戻り値がない場合ですね。
|
96
|
+
|
97
|
+
actionメソッドは `onChange(of:perform:)` のperformパラメータに渡していますが、
|
98
|
+
このパラメータは `@escaping (V) -> Void` の型ということになっています。
|
99
|
+
戻り値がVoidの型を要求していますので、Stringに変更したものはこの型に合わず、
|
100
|
+
エラーになっていると思います。
|
101
|
+
|
102
|
+
[onChange(of:perform:) | Apple Developer Documentation](https://developer.apple.com/documentation/swiftui/view/onchange(of:perform:))
|
103
|
+
|
104
|
+
ですので、actionの中からビューのプロパティに直接設定するとか、
|
105
|
+
(戻り値で返すのではなく)
|
106
|
+
そういう感じになるのかなと思います。
|
107
|
+
|
108
|
+
その先の具体的な処理の内容をご提示いただけましたら、
|
109
|
+
もう少し具体的な回答ができるかもしれません。
|
110
|
+
|
1
コードにViewも追記しました。コメントも追記しました。
test
CHANGED
@@ -11,38 +11,76 @@
|
|
11
11
|
*言語のバージョンが上がってもっと良い書き方ができるのかどうかまではわかりません・・
|
12
12
|
|
13
13
|
```swift
|
14
|
+
struct ContentView: View {
|
14
|
-
|
15
|
+
@State var photoPickerItems: [PhotosPickerItem] = []
|
15
|
-
|
16
|
+
var body: some View {
|
17
|
+
//QR画像選択
|
18
|
+
PhotosPicker(
|
19
|
+
selection: $photoPickerItems, // Bindingした[PhotosPickerItem]
|
20
|
+
maxSelectionCount: 1, // 選択する写真の数(0で無制限)
|
21
|
+
selectionBehavior: .ordered, // 順番が関係するか
|
22
|
+
matching: .images, // 写真の種類を選択(nilでどれでも可に)
|
23
|
+
preferredItemEncoding: .current, // エンコードの種類(基本currentでいいはず)
|
16
|
-
|
24
|
+
photoLibrary: .shared()){ // ライブラリの選択
|
17
|
-
|
25
|
+
Text("QRコードを読み込む")
|
26
|
+
.foregroundColor(MyColor.HighlightColor)
|
27
|
+
}
|
28
|
+
.onChange(of: photoPickerItems, perform: action) // ***** onChange(of:perform:) modifierでphotoPickerItemsが変わったら処理が動くようにします。
|
18
29
|
}
|
30
|
+
// ***** 写真を選択してphotoPickerItemsが変わったら呼び出されるメソッドです。
|
19
|
-
|
31
|
+
func action(equatable: any Equatable) {
|
20
|
-
let options1: [String : Any] = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
|
21
|
-
let qrDetector = CIDetector(ofType: CIDetectorTypeQRCode, context: context, options: options1)
|
22
|
-
guard let
|
32
|
+
guard let items = equatable as? [PhotosPickerItem] else {
|
23
|
-
return
|
33
|
+
return
|
34
|
+
}
|
35
|
+
Task {
|
36
|
+
// ***** photoPickerItemsは配列ですので(選択できるのは1つに限定しているとは思いますが)、配列の数だけ繰り返します。
|
37
|
+
for item in items {
|
38
|
+
// ***** PhotosPickerItemをData型に変換して、さらにUIImage型に変換します。
|
39
|
+
guard let data = try? await item.loadTransferable(type: Data.self),
|
40
|
+
let image = UIImage(data: data) else {
|
41
|
+
continue
|
42
|
+
}
|
43
|
+
// ***** UIImageからQRコードを検出します。
|
44
|
+
// ***** 1つの画像から複数のQRコードが検出されるとfeatures配列の要素は複数になると思います。
|
45
|
+
// ***** QRコードが検出できない場合はfeatures配列は要素数が0になると思います。
|
46
|
+
let features = detectQRCode(image)
|
47
|
+
for feature in features {
|
48
|
+
// ***** QRコードが正しく検出できたらmessageStringにURLが入っているはずです。
|
49
|
+
print(feature.messageString ?? "nope") // https://jingged.com
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
24
53
|
}
|
54
|
+
// ***** UIImageからQRコードを検出するメソッドです。
|
55
|
+
func detectQRCode(_ image: UIImage?) -> [CIQRCodeFeature] {
|
56
|
+
guard let image = image,
|
57
|
+
let ciImage = CIImage(image: image) else {
|
58
|
+
return []
|
59
|
+
}
|
60
|
+
let context = CIContext()
|
61
|
+
let options1: [String : Any] = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
|
62
|
+
guard let qrDetector = CIDetector(ofType: CIDetectorTypeQRCode, context: context, options: options1) else {
|
63
|
+
return []
|
64
|
+
}
|
25
|
-
let options2: [String : Any] = ciImage.properties.keys.contains((kCGImagePropertyOrientation as String)) ?
|
65
|
+
let options2: [String : Any] = ciImage.properties.keys.contains((kCGImagePropertyOrientation as String)) ?
|
26
|
-
[CIDetectorImageOrientation: ciImage.properties[(kCGImagePropertyOrientation as String)] ?? 1] :
|
66
|
+
[CIDetectorImageOrientation: ciImage.properties[(kCGImagePropertyOrientation as String)] ?? 1] :
|
27
|
-
[CIDetectorImageOrientation: 1]
|
67
|
+
[CIDetectorImageOrientation: 1]
|
28
|
-
let features = qrDetector.features(in: ciImage, options: options2)
|
68
|
+
let features = qrDetector.features(in: ciImage, options: options2)
|
29
|
-
return features
|
30
|
-
}
|
31
|
-
|
32
|
-
// 呼び出し側のイメージです。
|
33
|
-
func action() {
|
34
|
-
// PhotosPickerItem.loadTransferableなどを使って画像をUIImage型にしておきます。
|
35
|
-
// PhotosPickerItem -> Data -> UIImageの順番で変換するイメージでしょうか?
|
36
|
-
// https://developer.apple.com/documentation/photokit/photospickeritem
|
37
|
-
let image: UIImage = #imageLiteral(resourceName: "qrcode")
|
38
|
-
guard let features = detectQRCode(image) else {
|
39
|
-
return
|
40
|
-
}
|
41
|
-
let qrCodeFeatures = features.compactMap({ $0 as? CIQRCodeFeature })
|
69
|
+
let qrCodeFeatures = features.compactMap({ $0 as? CIQRCodeFeature })
|
42
|
-
|
70
|
+
return qrCodeFeatures
|
43
|
-
// QRコードが正しく検出できたらmessageStringにURLが入っているはずです。
|
44
|
-
print(feature.messageString ?? "nope")
|
45
71
|
}
|
46
72
|
}
|
47
73
|
```
|
48
74
|
|
75
|
+
### 追記です。
|
76
|
+
|
77
|
+
コメントありがとうございます。
|
78
|
+
|
79
|
+
説明不足ですみません・・
|
80
|
+
SwiftUIのViewの記述からコードを記載するようにしてみました。
|
81
|
+
今回はもう少しコメントも記述してみました。
|
82
|
+
「// *****」のコメントも読んでみてください。
|
83
|
+
|
84
|
+
> messageStringにurlを代入するのでしょうか?
|
85
|
+
messageStringに欲しい結果(URL)が格納されていますので、それを使って何か必要な処理を書いてみてください。
|
86
|
+
|