今回の内容
- 最近、
DispatchQueue.main.asyncAfter
をよく使ってましたが、データの取得が終わった時にUITableView
に表示させる為にDispatchGroup
の.leave
と.notify
を使用してます。
コード
Model
GetDataDetailModel
struct GetDataDetailModel{
let mediumImageURL:String?
let itemName:String?
let itemPrice:Int?
let itemCaption:String?
}
AlamofireProcess
import Alamofire
import SwiftyJSON
class AlamofireProcess{
public var getDataResultArray = [GetDataDetailModel]()
private var keyword:String?
init(getKey:String?){
keyword = getKey
}
}
extension AlamofireProcess{
public func getItemDetailData(completion: @escaping() -> Void){
guard let key = keyword else { return }
let apiKey = "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706?format=json&keyword=\(key.urlEncoded)&applicationId=作成したアプリID"
AF.request(apiKey, method: .get, parameters: nil, encoding: JSONEncoding.default).responseJSON {[self] response in
switch response.result{
case .success:
let jsonDetail = JSON(response.data as Any)
getDataResultArray = []
for dataCount in 0..<jsonDetail["Items"].count{
if let getMediumImageURL = jsonDetail["Items"][dataCount]["Item"]["mediumImageUrls"][0]["imageUrl"].string,
let getItemName = jsonDetail["Items"][dataCount]["Item"]["itemName"].string,
let getItemPrice = jsonDetail["Items"][dataCount]["Item"]["itemPrice"].int,
let getItemCaption = jsonDetail["Items"][dataCount]["Item"]["itemCaption"].string{
getDataResultArray.append(GetDataDetailModel(mediumImageURL: getMediumImageURL,
itemName: getItemName,
itemPrice: getItemPrice,
itemCaption: getItemCaption))
}
}
completion()
case .failure:
completion()
}
}
}
}
extension String{
var urlEncoded:String{
let charset = CharacterSet.alphanumerics.union(.init(charactersIn: "/?-._~"))
let remove = removingPercentEncoding ?? self
return remove.addingPercentEncoding(withAllowedCharacters: charset) ?? remove
}
}
View
Main.storyboard

SearchResultCell

SearchResultCell
import UIKit
class SearchResultCell: UITableViewCell {
@IBOutlet weak var mediumImageView: UIImageView!
@IBOutlet weak var itemNameLabel: UILabel!
@IBOutlet weak var itemPriceLabel: UILabel!
@IBOutlet weak var itemCaptionView: UITextView!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func prepareForReuse() {
super.prepareForReuse()
mediumImageView.image = UIImage(named: "")
itemNameLabel.text = ""
itemPriceLabel.text = ""
itemCaptionView.text = ""
}
}
Controller
import UIKit
import SDWebImage
class ViewController: UIViewController {
@IBOutlet weak var searchTextField: UITextField!
@IBOutlet weak var searchButton: UIButton!
@IBOutlet weak var resultTableView: UITableView!
private let alamofireProcess = AlamofireProcess(getKey: nil)
private let dispatchGroup = DispatchGroup()
private let dispachQueue = DispatchQueue(label: "alamofire",attributes: .concurrent)
private var cellContentsArray = [GetDataDetailModel]()
override func viewDidLoad() {
super.viewDidLoad()
resultTableView.register(UINib(nibName: "SearchResultCell", bundle: nil), forCellReuseIdentifier: "ItemDetailCell")
resultTableView.delegate = self
resultTableView.dataSource = self
}
@IBAction func search(_ sender: UIButton) {
let afProcess = AlamofireProcess(getKey: searchTextField.text)
dispatchGroup.enter()
dispachQueue.async {[self] in
afProcess.getItemDetailData {
self.dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .main){ [self] in
cellContentsArray = afProcess.getDataResultArray
print(cellContentsArray)
resultTableView.reloadData()
}
}
}
extension ViewController:UITableViewDelegate{
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return tableView.frame.height / 2.4
}
}
extension ViewController:UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellContentsArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemDetailCell", for: indexPath) as! SearchResultCell
cell.mediumImageView.sd_setImage(with: URL(string: cellContentsArray[indexPath.row].mediumImageURL!), completed: nil)
cell.itemNameLabel.text = cellContentsArray[indexPath.row].itemName
cell.itemPriceLabel.text = String(cellContentsArray[indexPath.row].itemPrice!) + "円"
cell.itemCaptionView.text = cellContentsArray[indexPath.row].itemCaption
return cell
}
}
終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。