Created
May 1, 2019 09:39
-
-
Save banjun/448eb4727801fe190ef72aed9cd2307f to your computer and use it in GitHub Desktop.
macOS screenshots Photos access via MLMediaLibrary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
import MediaLibrary | |
/// requires NSPhotoLibraryUsageDescription in info.plist | |
/// requires Pictures access in sandbox settings | |
final class PhotoSource: NSObject { | |
let photosLibrary = MLMediaLibrary(options: [ | |
MLMediaLoadSourceTypesKey: MLMediaSourceType.image.rawValue, | |
MLMediaLoadIncludeSourcesKey: [MLMediaSourcePhotosIdentifier], | |
MLMediaLoadExcludeSourcesKey: [MLMediaSourcePhotoBoothIdentifier], | |
]) | |
private var mediaSources: [String: MLMediaSource] = [:] { | |
didSet { | |
photoSource = mediaSources[MLMediaSourcePhotosIdentifier] | |
} | |
} | |
var photoSource: MLMediaSource? { | |
didSet { | |
NSLog("photoSource = %@", photoSource.debugDescription) | |
guard let s = photoSource else { return } | |
kvos.append(s.observe(\.rootMediaGroup, options: .new) { [unowned self] _, _ in | |
self.rootMediaGroup = self.photoSource?.rootMediaGroup | |
}) | |
_ = s.rootMediaGroup // async load | |
} | |
} | |
var rootMediaGroup: MLMediaGroup? { | |
didSet { | |
NSLog("rootMediaGroup = %@", rootMediaGroup.debugDescription) | |
guard let g = rootMediaGroup else { return } | |
screenshotGroup = g.childGroups? | |
.first {$0.typeIdentifier == MLPhotosAlbumsGroupTypeIdentifier}? | |
.childGroups? | |
.first {$0.typeIdentifier == MLPhotosScreenshotGroupTypeIdentifier} | |
} | |
} | |
var screenshotGroup: MLMediaGroup? { | |
didSet { | |
NSLog("screenshotGroup = %@", screenshotGroup.debugDescription) | |
guard let g = screenshotGroup else { return } | |
kvos.append(g.observe(\.mediaObjects, options: .new) { [unowned self] _, _ in | |
self.screenshots = self.screenshotGroup?.mediaObjects ?? [] | |
}) | |
_ = g.mediaObjects // async load | |
} | |
} | |
@objc dynamic var screenshots: [MLMediaObject] = [] { | |
didSet { | |
// NSLog("screenshots = %@", screenshots.debugDescription) | |
NSLog("%d screenshots", screenshots.count) | |
} | |
} | |
private var kvos: [NSKeyValueObservation] = [] | |
override init() { | |
super.init() | |
kvos.append(photosLibrary.observe(\.mediaSources) { [unowned self] _, _ in | |
self.mediaSources = self.photosLibrary.mediaSources ?? [:] | |
}) | |
_ = photosLibrary.mediaSources // async load | |
} | |
} | |
class ViewController: NSViewController { | |
let photoSource = PhotoSource() | |
private var kvos: [NSKeyValueObservation] = [] | |
private var screenshots: [MLMediaObject] = [] { | |
didSet { | |
guard let sample = screenshots.last else { return } | |
// requires thumbnailURL access (sandbox related) | |
guard let thumbnail = (sample.thumbnailURL.flatMap {try? Data(contentsOf: $0)}) else { return } | |
self.view.layer?.contents = NSImage(data: thumbnail) | |
self.view.layer?.contentsGravity = .resizeAspect | |
} | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
kvos.append(photoSource.observe(\.screenshots, options: .new) { [unowned self] _, _ in | |
self.screenshots = self.photoSource.screenshots | |
}) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment