Closed ShuheiYoshidaJP closed 3 years ago
textViewを編集不可に設定 メールアドレスを削除 bottomを一致(safeArea→superView)
2回目のログインだとログインをスキップさせる機能を復活させた
LoginVCのviewDidLoadメソッド内
今までErrorViewクラスのcheckSafeAreaメソッドの引数でViewControllerを引き渡し、 メソッド内でViewControllerのnavBarとTabBarを取得していたが、 今までの修正の影響でtabBarがメソッド内で取得できないことが判明した。 原因は不明。
https://github.com/shinonome-inc/mobile_shu_mogi_Qclient/issues/34#issuecomment-787400984 の原因が特定でき、解決できた
問題が起っているのはArticlePageのみ ErrorView作成当時はArticlePageがPush遷移だった ErrorView作成後、ArticlePageをModal遷移に変更したため ArticlePageにはTabBarが存在しない仕様になった
ErrorViewのcheckSafeAreaメソッドは navControllerとtabControllerのどちらかがnilだと機能しないようにしている よってArticlePageにおいてtabbarがnilだったため 今回の不具合がおきた
tabBarControllerがnilだった場合、tabBarHeightを0にする
ErrorViewクラスにて
func checkSafeArea(viewController: UIViewController) {
let tabBarController = viewController.tabBarController
guard let navBarController = viewController.navigationController else { return }
guard let tabBarHeight = tabBarController != nil ? tabBarController?.tabBar.frame.height : 0 else { return }
let navBarHeight = navBarController.navigationBar.frame.height
let height = viewController.view.frame.height - tabBarHeight - navBarHeight
frame = CGRect(x: 0.0,
y: navBarHeight,
width: viewController.view.frame.width,
height: height)
}
現状では以下のようにdataItemsを定義しているため dataItemsに変更があれば、tableViewのリロードが行われる https://github.com/shinonome-inc/mobile_shu_mogi_Qclient/blob/90c4faf65b546f68de3ed998c1195c1fbd066031/Qcli/ViewController/FeedViewController.swift#L15-L19
これをデータ取得が終わってからリロードさせたいため 以下のコードに書き換えた
var dataItems = [ArticleData]()
現状でのデータ取得メソッドは以下のコードで行っている https://github.com/shinonome-inc/mobile_shu_mogi_Qclient/blob/90c4faf65b546f68de3ed998c1195c1fbd066031/Qcli/ViewController/FeedViewController.swift#L78-L105 このコードでの問題点は 仮に93行目と94行目の間にtableViewのリロード処理をはさむと 以下の問題が発生する https://github.com/shinonome-inc/mobile_shu_mogi_Qclient/issues/21#issuecomment-769615998 ↑dataItems更新の前にtableViewのリロードが行われてしまう
したがって dataItemsの更新終了後にtableViewの更新を行いたいため 以下のメソッドを用意した
func storingData(dataArray: [AirticleModel], completion: () -> Void) {
dataArray.forEach { (oneAirticleData) in
if let title = oneAirticleData.title,
let createdAt = oneAirticleData.createdAt,
let like = oneAirticleData.likesCount,
let imageURL = oneAirticleData.user.profileImageUrl,
let articleURL = oneAirticleData.url,
let id = oneAirticleData.user.id {
let oneData = ArticleData(id: id, imgURL: imageURL, titleText: title, createdAt: createdAt, likeNumber: like, articleURL: articleURL)
self.dataItems.append(oneData)
} else {
print("ERROR: This data ↓ allocation failed.")
print(oneAirticleData)
}
}
completion()
}
またデータ取得のメソッドを以下のように書き換えた
func getData(requestAirticleData: AirticleDataNetworkService) {
requestAirticleData.fetch(success: { (dataArray) in
guard let dataArray = dataArray else { return }
self.storingData(dataArray: dataArray,
completion: {
self.articleTableView.reloadData()
print("👍 Reload the article data")
self.isNotLoading = true
})
}, failure: { error in
print("Failed to get the article list data.")
if let error = error {
print(error)
}
self.isNotLoading = true
//TODO: エラー画面を作成し、遷移させる
})
}
クロージャを使ってdataItemsを更新してから tableViewのリロードを行うようにした
https://github.com/shinonome-inc/mobile_shu_mogi_Qclient/issues/34#issuecomment-787601900 こちらの修正の後に正常にデータ取得して、tableViewのUI更新ができるかを検証した
下スクロールのデータ取得・UI更新は成功した
pull to refreshをすると以下のエラーが表示された
Fatal error: Index out of range
デバッグをとるために以下のような出力を tableView -> UITableViewCell メソッド内に配置した
print("test: \(indexPath.row)/\(dataItems.count)")
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = articleTableView.dequeueReusableCell(withIdentifier: "ArticleCell", for: indexPath) as? ArticleTableViewCell else {
abort()
}
print("test: \(indexPath.row)/\(dataItems.count)")
let model = dataItems[indexPath.row]
cell.setModel(model: model)
return cell
}
再度pull to refreshの検証を行った
test: 0/20
test: 1/20
test: 2/20
test: 3/20
test: 4/20
test: 5/20
test: 6/20
test: 7/20
test: 8/20
test: 9/20
test: 10/20
test: 11/20
test: 5/0
最後の
test: 5/0
が表示された時にエラーが起こったことがわかった
pull to refreshが呼び出してくるメソッド内に原因があるのではないかと思った https://github.com/shinonome-inc/mobile_shu_mogi_Qclient/blob/90c4faf65b546f68de3ed998c1195c1fbd066031/Qcli/ViewController/FeedViewController.swift#L114-L121 このメソッド内の
dataItems.removeAll()
が処理されて、dataItemsのcountが0になってしまうことがわかった
dataItems.removeAll()
を削除する これを行うことで新しく得たデータはtableViewの最下のCellから反映される getDataメソッドが実行される前に あらかじめ
let beforeFetchDataCount = dataItems.count
でTableViewに表示されているデータ数を取得しておく そしてデータ取得後に上からbeforeFetchDataCountの分だけ dataItemsのデータを削除して tableViewをリロードさせる。
以前考えていた対処方法同様 refreshメソッドにおいて https://github.com/shinonome-inc/mobile_shu_mogi_Qclient/blob/90c4faf65b546f68de3ed998c1195c1fbd066031/Qcli/ViewController/FeedViewController.swift#L114-L121 から
dataItems.remove()
を削除する
getDataメソッドの引数にisRefreshのブール値を用意する(デフォルトなfalse) 全てのデータが取得し終わった時に isRefreshがtrueの場合に前回の取得データを削除して 新しく取得したデータだけを残す https://github.com/shinonome-inc/mobile_shu_mogi_Qclient/blob/e2a951a1b3eb0bfdd63b7c75cbc2d526406e15ca/Qcli/ViewController/FeedViewController.swift#L74-L95
この処理によって dataItemsが空になることを避けることができ tableViewに何も表示される状態がないようにすることができた
作業ブランチ
feature/#34fix_reload_tableView_logic
現在のデータ取得→tableViewリロードのロジック
dataItemsが更新されるたびにリロード
目標のデータ取得→tableViewリロードロジック
一回のデータ取得で得られたデータが全てdataItemsに格納されたら tableViewをリロードする
他の修正ポイント
プライバシーポリシー・利用規約ページにおいてメールアドレスの削除・編集を無効にする 2回目以降のログインを飛ばす機能を復活させる