我正在尝试从集合视图中的 API 获取图像:
import UIKit
struct Images: Decodable {
let images = [imageUrl]()
}
struct imageUrl: Decodable {
let imageloc: String
}
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
@IBOutlet weak var CollectionView: UICollectionView!
var imageses = [Images]()
override func viewDidLoad() {
super.viewDidLoad()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageses.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let url = URL(string: "http://swaminarayanwales.org.uk/DailyDarshan/ExportJsonV2.php?sMandir=Nairobi-Temple&Target=real&sm=sm%20)")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data else { return }
do{
let jsonData = try JSONDecoder().decode([Images].self, from: data)
if let imgUrl = URL(string: jsonData[indexPath.row].images[indexPath.row].imageloc){
if let data = try? Data(contentsOf: imgUrl){
cell.imageView.image = UIImage(data: data)
}
}
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
catch{
print("error while decoding")
}
}.resume()
return cell
}
}
我没有 Xib 作为收集单元
import UIKit
class CollectionViewCell: UICollectionViewCell {
@IBOutlet weak var ImageView: UIImageView!
}
当我尝试从 API 获取响应时,它会在日志文件中为我提供正确的操作,因此 API 没有问题, 但我无法在集合视图中加载图像响应。
我制作了两个结构,第二个结构在第一个结构中用作数组,因为在 API 中图像是数组形式。
当我运行项目时,我没有得到任何输出......
这是API的输出
{
"mandir": "Nairobi-Temple",
"ShortName": "Nairobi EASST",
"date": "09\/01\/2021",
"fdate": "09 Jan 21",
"ImageFolder": "DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021",
"images": [{
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/1.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/10.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/11.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/12.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/13.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/14.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/15.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/16.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/2.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/3.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/4.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/5.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/6.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/7.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/8.jpg",
"imageDimension": "485:1024"
}, {
"imageloc": "http:\/\/swaminarayanwales.org.uk\/DailyDarshan\/DailyDarshanNairobi-EASST\/09-01-2021\/\/9.jpg",
"imageDimension": "485:1024"
}]
}
我的结构已经在顶部提到了。
您的代码中存在一些严重的设计错误。
首先,永远不要在
cellForRow/Item
中同步加载图像。
另一个错误是 JSON 的根对象是一个字典,所以它是 Images.self
但首先要注意的事情。
给结构体赋予更有意义的名称,并将 url 字符串直接解码为 URL
struct ImageData : Decodable {
let images : [Location]
}
struct Location: Decodable {
let imageloc: URL
}
要异步加载图像而不是在集合视图数据源方法内,请使用
DispatchGroup
一张一张地加载图像,并在所有图像可用时发出通知。
将数据源数组声明为
UIImage
的数组
var images = [UIImage]()
并将
callAPI()
替换为
func callAPI(){
let url = URL(string: "http://swaminarayanwales.org.uk/DailyDarshan/ExportJsonV2.php?sMandir=Nairobi-Temple&Target=real&sm=sm")!
let task = URLSession.shared.dataTask(with: url){ data, response, error in
if let error = error { print(error); return }
do {
let imageData = try JSONDecoder().decode(ImageData.self, from: data!)
let imageURLs = imageData.images.map(\.imageloc)
let group = DispatchGroup()
for imageURL in imageURLs {
group.enter()
URLSession.shared.dataTask(with: imageURL){ data, response, error in
defer{ group.leave() }
if let error = error { print(error); return }
if let image = UIImage(data: data!) {
self.images.append(image)
}
}.resume()
}
group.notify(queue: .main) {
self.collectionView.reloadData()
}
} catch {
print(error)
}
}
task.resume()
}
现在集合视图数据源方法很简单
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
cell.imageView.image = images[indexPath.row]
return cell
}
不要忘记在 Interface Builder 中将集合视图单元格的标识符设置为
Cell
。
您的代码中有两个问题
当您从 API 获取响应时,您需要填充数组“imageData”。
然后你需要通过调用reloadData()方法重新加载collectionView。