Saving Images to the Photo Library in SwiftUI
This article describes how to save images to the photo library in a SwiftUI app.
Prerequisites
Steps for iOS16+
Declare Permissions
Add the following to the Info.plist
file. Note that you must provide a specific use case, or your app may be rejected during App Store review. Guideline 5.1.1 - Legal - Privacy - Data Collection and Storage
xml
<key>NSPhotoLibraryAddUsageDescription</key>
<string>The app needs access to your photo library to save images, such as the Ghibli-style image generated by the app.</string>
Define MediaSaver
swift
import Photos
struct MediaSaver {
static func saveImageToPhotoLibrary(url: URL) async throws {
try await PHPhotoLibrary.shared().performChanges {
PHAssetCreationRequest.creationRequestForAssetFromImage(atFileURL: url)
}
}
static func saveVideoToPhotoLibrary(url: URL) async throws {
try await PHPhotoLibrary.shared().performChanges {
PHAssetCreationRequest.creationRequestForAssetFromVideo(atFileURL: url)
}
}
}
Using MediaSaver
swift
Task {
do {
try await MediaSaver.saveVideoToPhotoLibrary(url: videoURL)
} catch {
print(error.localizedDescription)
}
}
Steps for iOS15+
Declare Permissions
Add the following to the Info.plist
file
xml
<key>NSPhotoLibraryAddUsageDescription</key>
<string>The App wants to save images to the Photo Library</string>
Define ImageSaver
swift
// ImageSaver.swift
import UIKit
class ImageSaver: NSObject {
var successHandler: (() -> Void)?
var errorHandler: ((Error) -> Void)?
func writeToPhotoAlbum(image: UIImage) {
UIImageWriteToSavedPhotosAlbum(image, self, #selector(saveCompleted), nil)
}
@objc func saveCompleted(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
errorHandler?(error)
} else {
successHandler?()
}
}
}
Using ImageSaver
swift
// ContentView.swift
func savePhoto() {
guard let processedImage = processedImage else { return }
let imageSaver = ImageSaver()
imageSaver.successHandler = {
print("Success!")
}
imageSaver.errorHandler = {
print("Oops! \($0.localizedDescription)")
}
imageSaver.writeToPhotoAlbum(image: processedImage)
}