Media
Media copied to clipboard
A SwiftUI dynamic property wrapper for fetching media from your photo library. (iOS, tvOS, macOS)
Media
Also available as a part of my SwiftUI+ Collection – just add it to Xcode 13+
A package for simplifying the user of the camera and the user's photo library in SwiftUI.
Features
- Dynamic property wrappers for fetching media from the photo library
- Camera modifier for easily taking a photo
- ImagePicker modifier for allowing the user to pick a photo from their library
Note: Permission requests and Info.plist values are not handled by this framework. You should use the standard UI to perform these actions as usual.
Example
Fetch all asset collections of a given type and subtype:
// Its not necessary to `import Photos` as the framework does this for you.
import Media
struct AlbumsView: View {
@FetchAssetCollection(album: .album, kind: .albumRegular)
private var albums
var body: some View {
List(albums) { album in
Text(album.localizedTitle ?? "")
}
}
}
For camera or image picker implementations:
@State private var takePhoto: Bool = false
@State private var chooseFromLibrary: Bool = false
var body: some View {
VStack(spacing: 20) {
Button {
takePhoto = true
} label: {
Text("Take a photo")
}
.camera(isPresented: $takePhoto) { result in
print(try! result.get())
}
Button {
chooseFromLibrary = true
} label: {
Text("Choose from Library")
}
.imagePicker(isPresented: $chooseFromLibrary) { result in
print(try! result.get())
}
}
}
Inspiration
The property wrapper has heavily inspired by the new FetchRequest provided by SwiftUI. As such, it conforms to RandomAccessCollection allowing it to be used in all the same places, e.g. List, ForEach, etc...
This greatly simplifies the use of the photos framework library when integrating into a SwiftUI package.
Since the library is also a dynamic property, updates occuring in the users library are automatically tracked and reflecting in your SwiftUI views.
Custom Queries
The property wrapper initializers provide various overrides to ensure you can customize the queries you need to perform.
In cases where a convenience initializer hasn't been provided, you can simply pass your own PHFetchOptions instance:
private static var options: PHFetchOptions = {
let options = PHFetchOptions()
options.predicate = ...
return options
}()
@FetchAssetCollection(options)
private var custom
Supports API
PHAssetCollection
@FetchAssetCollection(
album: .smartAlbum,
filter: NSPredicate(
format: "NOT (assetCollectionSubtype IN %@)",
[
PHAssetCollectionSubtype.smartAlbumUserLibrary.rawValue,
PHAssetCollectionSubtype.smartAlbumAllHidden.rawValue,
PHAssetCollectionSubtype.smartAlbumFavorites.rawValue,
]
)
) var albums
PHCollectionList
@FetchCollectionList(
list: .smartFolder,
kind: .any
) private var folders
PHAsset
// You can instantiate your results during init:
@FetchAssetList
private var assets: MediaResults<PHAsset>
// Or, if you already have a set of results from a `PHFetchResult<PHAsset>` instance:
@FetchAssetList(results)
private var assets
// Alternatively, if you have a `PHAssetCollection` instance:
@FetchAssetList(in: collection)
private var assets
There are multiple overrides for all of the above to allow for most customizations, alternatively you can pass a PHFetchOptions instance yourself as mentioned above.
Exclusions
The primary purpose of this library is to simplify the usage of the Photos framework in SwiftUI applications. As such, permission requests and mutations are not included.
Those APIs are not an issue that needs fixing by this library.
Instead you should continue to use the existing APIs available via the Photos framework. Since the use of Photos types is required, the library automatically imports Photos for you so adding an additional import is redundant.
Installation
The code is packaged as a framework. You can install manually (by copying the files in the Sources directory) or using Swift Package Manager (preferred)
To install using Swift Package Manager, add this to the dependencies section of your Package.swift file:
.package(url: "https://github.com/SwiftUI-Plus/Media.git", .upToNextMinor(from: "1.0.0"))
Note: The package requires iOS v13+
Other Packages
If you want easy access to this and more packages, add the following collection to your Xcode 13+ configuration:
https://benkau.com/packages.json