Skip to content

Commit 4f4e5be

Browse files
author
Christian Elies
committed
feat(): implemented fetch all assets property wrapper; refactor(album): use fetch all assets property wrapper
1 parent 48edde4 commit 4f4e5be

File tree

3 files changed

+85
-24
lines changed

3 files changed

+85
-24
lines changed

Sources/MediaCore/API/Album/Album.swift

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import Photos
1111
/// Convenience wrapper type around `PHAssetCollection`
1212
///
1313
public struct Album {
14-
static var phAsset: PHAsset.Type = PHAsset.self
15-
1614
let phAssetCollectionWrapper: PHAssetCollectionWrapper
1715

1816
var phAssetCollection: PHAssetCollection? { phAssetCollectionWrapper.value }
@@ -58,6 +56,12 @@ public struct Album {
5856
@FetchAssets
5957
public var livePhotos: [LivePhoto]
6058

59+
/// All media (audios, live photos, photos, videos and more?) contained in the receiver
60+
/// sorted by `creationDate descending`.
61+
///
62+
@FetchAllAssets
63+
public var allMedia: [AnyMedia]
64+
6165
init(phAssetCollection: PHAssetCollection) {
6266
_audios = FetchAssets(in: phAssetCollection, sort: [Media.Sort(key: .creationDate, ascending: false)])
6367
_photos = FetchAssets(in: phAssetCollection, sort: [Media.Sort(key: .creationDate, ascending: false)])
@@ -67,31 +71,11 @@ public struct Album {
6771
filter: [.mediaSubtypes([.live])],
6872
sort: [Media.Sort(key: .creationDate, ascending: false)]
6973
)
74+
_allMedia = FetchAllAssets(in: phAssetCollection, sort: [Media.Sort(key: .creationDate, ascending: false)])
7075
phAssetCollectionWrapper = PHAssetCollectionWrapper(phAssetCollection: phAssetCollection)
7176
}
7277
}
7378

74-
public extension Album {
75-
/// All media (audios, live photos, photos, videos and more?) contained in the receiver
76-
/// sorted by `creationDate descending`
77-
///
78-
var allMedia: [AnyMedia] {
79-
guard let phAssetCollection = phAssetCollection else { return [] }
80-
81-
let options = PHFetchOptions()
82-
options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
83-
let result = Self.phAsset.fetchAssets(in: phAssetCollection, options: options)
84-
var media: [AnyMedia] = []
85-
result.enumerateObjects { asset, _, _ in
86-
guard let anyMedia = asset.anyMedia else {
87-
return
88-
}
89-
media.append(anyMedia)
90-
}
91-
return media
92-
}
93-
}
94-
9579
public extension Album {
9680
/// Creates an album with the given title
9781
///
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//
2+
// FetchAllAssets.swift
3+
// MediaCore
4+
//
5+
// Created by Christian Elies on 13.02.21.
6+
//
7+
8+
import Photos
9+
10+
/// Property wrapper for fetching all assets from the photo library.
11+
/// Fetches the assets lazily (after accessing the property).
12+
///
13+
@propertyWrapper
14+
public struct FetchAllAssets {
15+
static var phAsset: PHAsset.Type = PHAsset.self
16+
17+
private var assetCollection: PHAssetCollection?
18+
private let options = PHFetchOptions()
19+
private let defaultSort: Media.Sort<Media.SortKey> = Media.Sort(key: .creationDate, ascending: false)
20+
21+
/// Wrapped array of `AnyMedia` instances.
22+
public var wrappedValue: [AnyMedia] {
23+
let result: PHFetchResult<PHAsset>
24+
if let assetCollection = assetCollection {
25+
result = Self.phAsset.fetchAssets(in: assetCollection, options: options)
26+
} else {
27+
result = Self.phAsset.fetchAssets(with: options)
28+
}
29+
var media: [AnyMedia] = []
30+
result.enumerateObjects { asset, _, _ in
31+
guard let anyMedia = asset.anyMedia else {
32+
return
33+
}
34+
media.append(anyMedia)
35+
}
36+
return media
37+
}
38+
39+
/// Initializes the property wrapper using a default sort descriptor
40+
/// (sort by `creationDate descending`).
41+
///
42+
public init() {
43+
options.sortDescriptors = [defaultSort.sortDescriptor]
44+
}
45+
46+
/// Initializes the property wrapper using the given sort descriptors
47+
/// to define the `PHFetchOptions`.
48+
///
49+
/// - Parameters:
50+
/// - assetCollection: limits the fetch to a specific asset collection, by default all assets in the library are taken into account.
51+
/// - sort: a set of `Sort<MediaSortKey>` for sorting the assets
52+
/// - fetchLimit: a maximum number of results to fetch, defaults to 0 (no limit)
53+
/// - includeAllBurstAssets: a Boolean value that determines whether the fetch result includes all assets from burst photo sequences, defaults to false
54+
/// - includeHiddenAssets: a Boolean value that determines whether the fetch result includes assets marked as hidden, defaults to false
55+
///
56+
public init(
57+
in assetCollection: PHAssetCollection? = nil,
58+
sort: Set<Media.Sort<Media.SortKey>> = [],
59+
fetchLimit: Int = 0,
60+
includeAllBurstAssets: Bool = false,
61+
includeHiddenAssets: Bool = false
62+
) {
63+
self.assetCollection = assetCollection
64+
65+
var sortKeys = sort
66+
sortKeys.insert(defaultSort)
67+
68+
if !sortKeys.isEmpty {
69+
let sortDescriptors = sortKeys.map { $0.sortDescriptor }
70+
options.sortDescriptors = sortDescriptors
71+
}
72+
73+
options.fetchLimit = fetchLimit
74+
options.includeAllBurstAssets = includeAllBurstAssets
75+
options.includeHiddenAssets = includeHiddenAssets
76+
}
77+
}

Tests/MediaTests/Models/Album/AlbumTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ final class AlbumTests: XCTestCase {
1313
lazy var album = Album(phAssetCollection: mockAssetCollection)
1414

1515
override func setUp() {
16-
Album.phAsset = MockPHAsset.self
16+
FetchAllAssets.phAsset = MockPHAsset.self
1717
PHAssetFetcher.asset = MockPHAsset.self
1818
MockPHAsset.fetchResult.mockAssets.removeAll()
1919
AlbumFetcher.assetCollection = MockPHAssetCollection.self

0 commit comments

Comments
 (0)