Skip to content

Instantly share code, notes, and snippets.

@banjun
Created May 1, 2019 09:39
Show Gist options
  • Save banjun/448eb4727801fe190ef72aed9cd2307f to your computer and use it in GitHub Desktop.
Save banjun/448eb4727801fe190ef72aed9cd2307f to your computer and use it in GitHub Desktop.
macOS screenshots Photos access via MLMediaLibrary
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