Json : https://picsum.photos/v2/list
ContentView.swift
//
// ContentView.swift
// Swiftuitest
//
// Created by Cairocoders
//
import SwiftUI
struct ContentView: View {
@ObservedObject var items = Remote(url: URL(string: "https://picsum.photos/v2/list")!, transform: {
try? JSONDecoder().decode([Photo].self, from: $0)
})
var body: some View {
NavigationView {
if items.value == nil {
ProgressView()
.onAppear {
items.load()
}
}else {
List {
ForEach(items.value!) { photo in
NavigationLink(
destination:
PhotoView(photo.download_url),
label: {
Text(photo.author)
})
}
}.navigationTitle("Authors")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Model.swift
//
// Model.swift
// Swiftuitest
//
// Created by Cairocoders
//
import Foundation
struct Photo: Codable, Identifiable {
let id: String
let author: String
let width, height: Int
let url, download_url: URL
}
struct PhotoLoadingError: Error {}
//View Model
final class Remote<Asc>: ObservableObject {
@Published var result: Result<Asc, Error>? = nil
var value: Asc? { try? result?.get()}
let url:URL
let transform: (Data) ->Asc?
init(url: URL, transform: @escaping (Data) ->Asc?) {
self.url = url
self.transform = transform
}
func load() {
URLSession.shared.dataTask(with: url) { (data, _, _) in
DispatchQueue.main.async {
if let d = data, let v = self.transform(d) {
self.result = .success(v)
} else {
self.result = .failure(PhotoLoadingError())
}
}
}.resume()
}
}
PhotoView.swift
//
// PhotoView.swift
// Swiftuitest
//
// Created by Cairocoders
//
import SwiftUI
struct PhotoView: View {
@ObservedObject var image: Remote<UIImage>
init(_ url: URL) {
self.image = Remote(url: url, transform: {
UIImage(data: $0)
})
}
var body: some View {
Group {
if image.value == nil {
ProgressView()
.onAppear { image.load() }
} else {
Image(uiImage: image.value!)
.resizable()
.aspectRatio(contentMode: .fit)
}
}
}
}
