[OS]Table Viewの整理(1)
こんにちは.今日の目標はiOSにおけるtableViewの実現モデルを全面的にまとめ、移行することです!
習ったくせに書くときは覚えてない
このシリーズは、次の順序で作成されます.ちょっと長いかな?
1.URLセッションを使用してTable Viewにデータを表示する
より効率的なコードの作成
AlamoFire、KingFisherの適用
この記事では,最も基本的なURLセッション通信とTable Viewの基本的な動作を実現する.
まずこのサイトNewsApiに会員登録してapi鍵を受け取ってください
それから書類を見て、私は最高のタイトルを書きます.
リンクは「https://newsapi.org/v2/top-headlines?」
キーライン
country = kr
apiKey=発行済みapiキー
使用します.
PostManでテストします.
私は2つのarticles配列しか使いません.そのうちの1つはtitleで、1つはurlToImageです.
では、以下のようにモデルを作成できますか?
NetWorkという構造を作成し、ここで通信し、結果値を返します.
エラー処理の列挙
Customcellの作成
あ、それからまず!画像はurlからダウンロードされず、デフォルトの画像が使用されます.
よく撮れているか確認できますよね?
まず、imageURLがあれば、そのURLから画像を受信することを実現します.
Cellの内容なのでCellForRowで実現しましょう
cellで次の関数を作成しました.
バックグラウンドスレッドからurlの画像をダウンロードし、メインスレッドにuiを更新させます!
?????
うん.ちょっと変な感じ
まずレイアウトがめちゃくちゃなのは….うん.
まずプレースホルダ画像を指定してgetImage関数を呼び出すべきだと思います.
このようにしてこそ、画像とラベルのコンストレイントが正常に実行されます.
私はまずこの問題を解決します.
CellForRowはまずplaceHolderに画像を指定します.
cell.getImage関数が非同期で呼び出されました
このセクションのInfoが表示されます.App Transportセキュリティ設定をplistに追加します.
サブキーを使用してAllow Arbitrary Loadsを追加し、値をYESに変更します.
効果が確認できてとても良かったです!
でも.これは本当に最高ですか?
最高のレベルではないでしょうか.これでもいいですか.
今のやり方の問題を考えてみましょう.
あと文章が長すぎるので続きを書きましょう!
完全なコードは、次のリンクgithub repoにあります.
習ったくせに書くときは覚えてない
このシリーズは、次の順序で作成されます.ちょっと長いかな?
使用するデータ:NewsAPI
1.URLセッションを使用してTable Viewにデータを表示する
より効率的なコードの作成
AlamoFire、KingFisherの適用
1.NewsAPIを取得し、モデルを作成する
まずこのサイトNewsApiに会員登録してapi鍵を受け取ってください
それから書類を見て、私は最高のタイトルを書きます.
リンクは「https://newsapi.org/v2/top-headlines?」
キーライン
country = kr
apiKey=発行済みapiキー
使用します.
PostManでテストします.
私は2つのarticles配列しか使いません.そのうちの1つはtitleで、1つはurlToImageです.
では、以下のようにモデルを作成できますか?
import Foundation
struct NewsList: Decodable {
let articles: [Article]
}
struct Article: Decodable {
let title: String
let urlToImage: String?
}
2.通信api
NetWorkという構造を作成し、ここで通信し、結果値を返します.
エラー処理の列挙
enum NetworkError: Error {
case invalidURL
case unknown
case statusCodeError
case noData
case jsonError
}
result typeと@脱出閉パッケージを使用して、次の形式のdownLoadImage関数を作成します.static func downLoadImage(completion: @escaping (Result<[Article],NetworkError>) -> Void)
まずconfiguration、session、URLコンポーネント、requestを作成しますlet config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
guard var urlComponents = URLComponents(string: link) else {
completion(.failure(NetworkError.invalidURL))
return
}
let country = URLQueryItem(name: "country", value: "kr")
let apiKey = URLQueryItem(name: "apiKey", value: "967a51965f9e4eec9e13b5ca4adf46f6")
urlComponents.queryItems?.append(country)
urlComponents.queryItems?.append(apiKey)
guard let requestURL = urlComponents.url else {
completion(.failure(NetworkError.invalidURL))
return
}
その後taskを作成し、エラー処理を行い、do-catch文を使用して結果値を送信すればよいのではないでしょうか.let dataTask = session.dataTask(with: requestURL) { data, response, error in
guard error == nil else {
completion(.failure(NetworkError.unknown))
return
}
guard let statusCode = (response as? HTTPURLResponse)?.statusCode, (200..<300).contains(statusCode) else {
completion(.failure(NetworkError.statusCodeError))
return
}
guard let data = data else {
completion(.failure(NetworkError.noData))
return
}
do {
let decoder = JSONDecoder()
let result = try decoder.decode(NewsList.self, from: data).articles
print(result)
completion(.success(result))
} catch {
print(error)
completion(.failure(NetworkError.jsonError))
return
}
}
dataTask.resume()
最後に、リストにデータを保存し、tableViewを再ロードすると、すべてのデータが準備されます.NetWork.downLoadImage { [weak self] result in
switch result {
case .success(let data):
self?.list = data
DispatchQueue.main.async {
self?.tableView.reloadData()
}
case .failure(let error):
print(error)
}
}
3 tableViewで表示
Customcellの作成
class NewsCell: UITableViewCell {
@IBOutlet weak var contentImage: UIImageView!
@IBOutlet weak var title: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
title.numberOfLines = 0
title.font = .systemFont(ofSize: 20, weight: .bold)
title.minimumScaleFactor = 0.5
}
}
次に、CellForRow関数でデータをTable Viewに表示します.あ、それからまず!画像はurlからダウンロードされず、デフォルトの画像が使用されます.
よく撮れているか確認できますよね?
4.画像を表示
まず、imageURLがあれば、そのURLから画像を受信することを実現します.
Cellの内容なのでCellForRowで実現しましょう
cellで次の関数を作成しました.
バックグラウンドスレッドからurlの画像をダウンロードし、メインスレッドにuiを更新させます!
func getImage(_ str: String?){
guard str != nil, let url = URL(string: str!) else {
contentImage.image = UIImage(systemName: "photo.circle.fill")
return
}
DispatchQueue.global().async {
var tempImg: UIImage?
if let data = try? Data(contentsOf: url), let img = UIImage(data: data) {
tempImg = img
} else {
tempImg = UIImage(systemName: "photo.circle.fill")
}
DispatchQueue.main.async {
self.contentImage.image = tempImg
}
}
}
そしてcellForRowは対応する関数を呼び出します.cell.getImage(target.urlToImage)
そして運行すれば良いのでは??????
うん.ちょっと変な感じ
まずレイアウトがめちゃくちゃなのは….うん.
まずプレースホルダ画像を指定してgetImage関数を呼び出すべきだと思います.
このようにしてこそ、画像とラベルのコンストレイントが正常に実行されます.
私はまずこの問題を解決します.
CellForRowはまずplaceHolderに画像を指定します.
cell.getImage関数が非同期で呼び出されました
cell.contentImage.image = UIImage(systemName: "photo.circle.fill")
DispatchQueue.global().async {
cell.getImage(target.urlToImage)
}
getImage関数も次のように変更されました.func getImage(_ str: String?){
guard str != nil, let url = URL(string: str!) else {
return
}
if let data = try? Data(contentsOf: url), let img = UIImage(data: data) {
DispatchQueue.main.async {
self.contentImage.image = img
}
}
}
またimageURLにはhttpの常にエラーメッセージが表示されます.このセクションのInfoが表示されます.App Transportセキュリティ設定をplistに追加します.
サブキーを使用してAllow Arbitrary Loadsを追加し、値をYESに変更します.
効果が確認できてとても良かったです!
でも.これは本当に最高ですか?
最高のレベルではないでしょうか.これでもいいですか.
今のやり方の問題を考えてみましょう.
あと文章が長すぎるので続きを書きましょう!
完全なコードは、次のリンクgithub repoにあります.
Reference
この問題について([OS]Table Viewの整理(1)), 我々は、より多くの情報をここで見つけました https://velog.io/@aurora_97/RxSwift-TableView-정리하기-1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol