質問編集履歴
5
a
title
CHANGED
File without changes
|
body
CHANGED
@@ -88,33 +88,87 @@
|
|
88
88
|
|
89
89
|
```
|
90
90
|
|
91
|
+
## SearchRootVC全文
|
91
92
|
|
93
|
+
```SearchRootVC
|
92
|
-
|
94
|
+
import UIKit
|
93
95
|
|
96
|
+
class SearchRootVC: UITableViewController, UISearchBarDelegate {
|
97
|
+
|
98
|
+
@IBOutlet weak var searchBar: UISearchBar!
|
99
|
+
|
100
|
+
// Var
|
101
|
+
var word: String!
|
102
|
+
var url: String!
|
103
|
+
var RepoToPass: Int!
|
104
|
+
|
105
|
+
var task: URLSessionTask?
|
106
|
+
var repo: [[String: Any]]=[]
|
107
|
+
|
108
|
+
var repositoryApi = RepositoryApi()
|
109
|
+
|
110
|
+
override func viewDidLoad() {
|
111
|
+
super.viewDidLoad()
|
112
|
+
setupTableView()
|
113
|
+
}
|
114
|
+
|
115
|
+
// 以下3つ、元から用意されているsearchBar関数名なので、変更NG。
|
116
|
+
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
|
117
|
+
searchBar.text = ""
|
118
|
+
return true
|
119
|
+
}
|
120
|
+
|
121
|
+
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
|
122
|
+
task?.cancel()
|
123
|
+
}
|
124
|
+
|
125
|
+
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
|
126
|
+
repositoryApi.getRandomRepoUrlSession()
|
127
|
+
}
|
128
|
+
|
129
|
+
func setupTableView() {
|
130
|
+
// UISearchBarのdelegateプロパティに、self(=SearchRootVC)を代入。
|
131
|
+
searchBar.delegate = self
|
132
|
+
}
|
133
|
+
|
134
|
+
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
94
|
-
|
135
|
+
if segue.identifier == Segues.ToProfileDetail {
|
136
|
+
if let detailVC = segue.destination as? ProfileDetailVC {
|
137
|
+
detailVC.selectedUser = self
|
138
|
+
}
|
139
|
+
}
|
140
|
+
}
|
141
|
+
}
|
95
142
|
|
143
|
+
|
144
|
+
// extension
|
145
|
+
|
146
|
+
extension SearchRootVC {
|
147
|
+
|
148
|
+
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
149
|
+
return repo.count
|
150
|
+
}
|
151
|
+
|
152
|
+
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
153
|
+
|
154
|
+
// dequeueReusableCellで、セルを再利用。
|
155
|
+
// nilを返さない為、オプショナルバインディングは不要。
|
156
|
+
|
157
|
+
let cell: RepositoryCell = tableView.dequeueReusableCell(withIdentifier: Identifiers.RepositoryCell, for: indexPath) as! RepositoryCell
|
158
|
+
let UserRepo = repo[indexPath.row]
|
159
|
+
cell.configureCell(UserRepo)
|
160
|
+
cell.tag = indexPath.row
|
161
|
+
return cell
|
162
|
+
}
|
163
|
+
|
164
|
+
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
165
|
+
RepoToPass = indexPath.row
|
166
|
+
performSegue(withIdentifier: Segues.ToProfileDetail, sender: self)
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
96
170
|
```
|
97
|
-
// dataの強制アンラップを修正。
|
98
|
-
guard let data = data else { return }
|
99
|
-
|
100
|
-
// try!は、例外が発生したときにはクラッシュするので修正。(-> エラーが起こり得ないケースでのみ使用可)
|
101
|
-
// try?で例外を安全に無視できるが、エラーを表示するため do-catch を使用。
|
102
|
-
|
103
|
-
do {
|
104
|
-
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
|
105
|
-
if let items = json?["items"] as? [[String: Any]] {
|
106
|
-
self.repo = items
|
107
|
-
// DispatchQueue で一つ以上のタスクを管理し、async で複数のAPIの非同期通信を実行。
|
108
|
-
DispatchQueue.main.async {
|
109
|
-
// UIを更新する処理
|
110
|
-
self.tableView.reloadData()
|
111
|
-
}
|
112
|
-
}
|
113
|
-
} catch {
|
114
|
-
debugPrint(error.localizedDescription)
|
115
|
-
return
|
116
|
-
}
|
117
|
-
```
|
118
171
|
|
172
|
+
|
119
173
|
質問は以上です。
|
120
174
|
お時間あるときに、ご返信頂けましたら幸いです????
|
4
あ
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
self
|
1
|
+
do-catch内にてselfエラー【URLSessionを他クラスから呼び出したい。】
|
body
CHANGED
File without changes
|
3
あ
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
|
1
|
+
selfが原因の、EXC_BAD_ACCESSが出る【URLSessionを他クラスから呼び出したい。】
|
body
CHANGED
@@ -1,27 +1,96 @@
|
|
1
|
-
##
|
1
|
+
## やりたいこと
|
2
|
-
強制アンラップ、不必要なIUOを考慮してリファクタリングしたコードが2です。
|
3
|
-
安全性の低い点があれば、指摘して頂きたいです。
|
4
2
|
|
5
|
-
|
3
|
+
`SearchRootVC`クラスにて、**URLSession**のコードを`RepositoryApi`クラスから呼び出したい。
|
6
4
|
|
7
|
-
|
5
|
+
```SearchRootVC
|
6
|
+
var repositoryApi = RepositoryApi()
|
8
7
|
|
9
|
-
|
8
|
+
...
|
10
9
|
|
10
|
+
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
|
11
|
+
repositoryApi.getRandomRepoUrlSession()
|
12
|
+
}
|
11
13
|
```
|
14
|
+
|
15
|
+
```RepositoryApi
|
16
|
+
|
17
|
+
// URLSessionの処理
|
18
|
+
```
|
19
|
+
|
20
|
+
## selfが原因の、EXC_BAD_ACCESSが出る
|
21
|
+
|
22
|
+
`EXC_BAD_ACCESS`エラーにて、
|
23
|
+
|
24
|
+
`self = CodeCheck_Test_Yumemi.SearchRootVC 0x00007ff8c083db00`だと エラー原因が特定出来たので、
|
25
|
+
|
26
|
+
下記を記述して`self`の使用を避けようとしましたが、引き続き`EXC_BAD_ACCESS`でクラッシュします...
|
27
|
+
|
28
|
+
```RepositoryApi
|
29
|
+
var searchRootVC = SearchRootVC()
|
30
|
+
```
|
31
|
+
|
32
|
+
|
33
|
+
## URLSessionコード
|
34
|
+
|
35
|
+
なお、呼び出しをせずに`SearchRootVC`のみで実行すると
|
36
|
+
`EXC_BAD_ACCESS`は無く、正常に動作します。
|
37
|
+
|
38
|
+
```RepositoryApi
|
39
|
+
import UIKit
|
40
|
+
|
41
|
+
class RepositoryApi: SearchRootVC {
|
42
|
+
|
43
|
+
var searchRootVC = SearchRootVC()
|
44
|
+
|
45
|
+
|
46
|
+
func getRandomRepoUrlSession() {
|
47
|
+
|
48
|
+
let word = searchBar.text!
|
49
|
+
let REPOSITORY_URL = URL_BASE + "(word)"
|
50
|
+
|
51
|
+
// nilは許さない。urlの強制アンラップを修正。
|
52
|
+
guard let url = URL(string: REPOSITORY_URL) else { return }
|
53
|
+
|
54
|
+
let task = URLSession.shared.dataTask(with: url) { (data, responce, error) in
|
55
|
+
|
56
|
+
guard error == nil else {
|
57
|
+
debugPrint(error.debugDescription)
|
58
|
+
return
|
59
|
+
}
|
60
|
+
|
61
|
+
// dataの強制アンラップを修正。
|
62
|
+
guard let data = data else { return }
|
63
|
+
|
64
|
+
// try!は、例外が発生したときにはクラッシュするので修正。(-> エラーが起こり得ないケースでのみ使用可)
|
65
|
+
// try?で例外を安全に無視できるが、エラーを表示するため do-catch を使用。
|
66
|
+
|
67
|
+
do {
|
12
|
-
|
68
|
+
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
|
13
|
-
if let items =
|
69
|
+
if let items = json?["items"] as? [[String: Any]] {
|
14
|
-
self.repo = items
|
70
|
+
self.searchRootVC.repo = items
|
71
|
+
// DispatchQueue で一つ以上のタスクを管理し、async で複数のAPIの非同期通信を実行。
|
15
72
|
DispatchQueue.main.async {
|
16
73
|
// UIを更新する処理
|
17
|
-
self.tableView.reloadData()
|
74
|
+
self.searchRootVC.tableView.reloadData()
|
18
75
|
}
|
19
76
|
}
|
77
|
+
} catch {
|
78
|
+
debugPrint(error.localizedDescription)
|
79
|
+
return
|
80
|
+
}
|
81
|
+
}
|
82
|
+
// 新しく初期化されたタスクは一時停止状態で開始されるため、このメソッドを呼び出してタスクを開始する必要がある。
|
83
|
+
task.resume()
|
84
|
+
}
|
85
|
+
|
20
86
|
}
|
87
|
+
|
88
|
+
|
21
89
|
```
|
22
90
|
|
23
|
-
####2
|
24
91
|
|
92
|
+
## 追記
|
93
|
+
|
25
94
|
`let json`は、`guard let json`とすべきなのでしょうか?
|
26
95
|
|
27
96
|
```
|
@@ -47,6 +116,5 @@
|
|
47
116
|
}
|
48
117
|
```
|
49
118
|
|
50
|
-
|
119
|
+
質問は以上です。
|
51
|
-
|
52
120
|
お時間あるときに、ご返信頂けましたら幸いです????
|
2
あ
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
## JSONコード
|
1
|
+
## リファクタリングしたJSONコードの添削。
|
2
|
-
|
3
2
|
強制アンラップ、不必要なIUOを考慮してリファクタリングしたコードが2です。
|
4
3
|
安全性の低い点があれば、指摘して頂きたいです。
|
5
4
|
|
1
a
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
|
1
|
+
JSONコードにて、guard let jsonとすべきなのか。
|
body
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
##
|
1
|
+
## JSONコードにて、guard let jsonとすべきなのか。
|
2
2
|
|
3
3
|
強制アンラップ、不必要なIUOを考慮してリファクタリングしたコードが2です。
|
4
4
|
安全性の低い点があれば、指摘して頂きたいです。
|