Save images url to library (SwiftUI)
I am displaying a photo in the application following the link, how can I save this photo to my phone's library?
struct RemoteImage: View {
private enum LoadState {
case loading, success, failure
}
private class Loader: ObservableObject {
var data = Data()
var state = LoadState.loading
init(url: String) {
guard let parsedURL = URL(string: url) else {
fatalError("Invalid URL: \(url)")
}
URLSession.shared.dataTask(with: parsedURL) { data, response, error in
if let data = data, data.count > 0 {
self.data = data
self.state = .success
} else {
self.state = .failure
}
DispatchQueue.main.async {
self.objectWillChange.send()
}
}.resume()
}
}
@StateObject private var loader: Loader
var loading: Image
var failure: Indicator
var body: some View {
selectImage()
}
init(url: String, loading: Image = Image("loadingimage").resizable(), failure: Indicator = Indicator()) {
_loader = StateObject(wrappedValue: Loader(url: url))
self.loading = loading
self.failure = failure
}
@ViewBuilder private func selectImage() -> some View {
switch loader.state {
case .loading:
loading
case .failure:
failure
default:
if let image = UIImage(data: loader.data) {
Image(uiImage: image).resizable()
} else {
failure
}
}
}
}
I am trying to save a photo using .contextMenu
but by clicking on the button I get an error: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
RemoteImage(url: image.obr1)
.aspectRatio(contentMode: .fit)
.cornerRadius(15)
.overlay(Color.black.opacity(0.2))
.cornerRadius(15)
.contextMenu {
Button(action: {
let im = UIImage(named: "image.jpeg")!
UIImageWriteToSavedPhotosAlbum(im, nil,nil, nil)
}) {
HStack {
Text("Save")
Image(systemName: "square.and.arrow.down.fill")
}
}
}
What am I doing wrong ? I'm new to swift, thanks for any help
I edited my question, please help if anyone knows the answer
Solution 1:
Remove function and use direct code.
Button(action: {
let im = UIImage(named:"image.jpg")!
UIImageWriteToSavedPhotosAlbum(im, nil,nil, nil)
}) {
HStack {
Text("Save")
Image(systemName: "square.and.arrow.down.fill")
}
}
Or put your function outside the Button action and call the function inside the button action.