123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- // _____ _
- // |_ _| |_ _ _ ___ ___ _ __ __ _
- // | | | ' \| '_/ -_) -_) ' \/ _` |_
- // |_| |_||_|_| \___\___|_|_|_\__,_(_)
- //
- // Threema iOS Client
- // Copyright (c) 2019-2020 Threema GmbH
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License, version 3,
- // as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
- import Photos
- import UIKit
- import CocoaLumberjackSwift
- @objc class AlbumManager: NSObject {
- static let albumName = "Threema Media"
- let successMessage = "Successfully saved image to Camera Roll."
- let permissionNotGrantedMessage = "Permission to save images not granted"
- let writeErrorMessage = "Error writing to image library:"
- let generalError = "Could not create error message"
-
- @objc static let shared = AlbumManager()
-
- private var assetCollection: PHAssetCollection!
-
- private override init() {
- super.init()
-
- if let assetCollection = fetchAssetCollectionForAlbum() {
- self.assetCollection = assetCollection
- return
- }
- }
-
- private func checkAuthorizationWithHandler(completion: @escaping ((_ authorizationState: PhotosRights) -> Void)) {
- let accessAllowed = PhotosRightsHelper.checkAccessAllowed(rightsHelper: PhotosRightsHelper())
- completion(accessAllowed)
- }
-
- private func fetchAssetCollectionForAlbum() -> PHAssetCollection? {
- let fetchOptions = PHFetchOptions()
- fetchOptions.predicate = NSPredicate(format: "title = %@", AlbumManager.albumName)
- let collection = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)
-
- if let _: AnyObject = collection.firstObject {
- return collection.firstObject
- }
- return nil
- }
-
- @objc func save_ori(image: UIImage) {
- self.checkAuthorizationWithHandler { (authorizationState) in
- if authorizationState == .full, self.assetCollection != nil {
- PHPhotoLibrary.shared().performChanges({
- let assetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
- guard let assetPlaceHolder = assetChangeRequest.placeholderForCreatedAsset else {
- DDLogError("Could not create placeholder")
- return
- }
- if let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.assetCollection) {
- let enumeration: NSArray = [assetPlaceHolder]
- albumChangeRequest.addAssets(enumeration)
- }
-
- }, completionHandler: { (success, error) in
- if success {
- DDLogNotice(self.successMessage)
- } else {
- guard let err = error else {
- DDLogError(self.generalError)
- return
- }
- DDLogError(self.writeErrorMessage + "\(err.localizedDescription)")
- }
- })
- } else if authorizationState == .write || authorizationState == .potentialWrite {
- UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.savedImage), nil)
- } else {
- DDLogNotice(self.permissionNotGrantedMessage)
- }
- }
- }
-
- @objc func savedImage(_ im:UIImage, error:Error?, context:UnsafeMutableRawPointer?) {
- if ((error) != nil) {
- guard let err = error else {
- DDLogError(self.generalError)
- return
- }
- DDLogError(self.writeErrorMessage + "\(err.localizedDescription)")
- } else {
- DDLogNotice(successMessage)
- }
- }
-
- @objc func save(image: UIImage) {
- func saveIt(_ validAssets: PHAssetCollection){
- PHPhotoLibrary.shared().performChanges({
- let assetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
- if let assetPlaceHolder = assetChangeRequest.placeholderForCreatedAsset {
- if let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.assetCollection) {
- let enumeration: NSArray = [assetPlaceHolder]
- albumChangeRequest.addAssets(enumeration)
- }
- }
- }, completionHandler: { (success, error) in
- if success {
- DDLogNotice(self.successMessage)
- } else {
- guard let err = error else {
- DDLogError(self.generalError)
- return
- }
- DDLogError(self.writeErrorMessage + "\(err.localizedDescription)")
- }
- })
- }
- self.checkAuthorizationWithHandler { (authorizationState) in
- if authorizationState == .full {
- if let validAssets = self.assetCollection { // Album already exists
- saveIt(validAssets)
- } else {
- PHPhotoLibrary.shared().performChanges({
- PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: AlbumManager.albumName) // create an asset collection with the album name
- }) { success, error in
- if success, let validAssets = self.fetchAssetCollectionForAlbum() {
- self.assetCollection = validAssets
- saveIt(validAssets)
- } else {
- DDLogError(self.writeErrorMessage + " \(error!.localizedDescription)")
- }
- }
- }
- } else if authorizationState == .write || authorizationState == .potentialWrite {
- UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.savedImage), nil)
- } else {
- DDLogNotice(self.permissionNotGrantedMessage)
- }
- }
- }
-
- @objc func save(url: URL, isVideo: Bool, completionHandler: @escaping ((_ success: Bool) -> Void)) {
- func saveIt(_ validAssets: PHAssetCollection){
- PHPhotoLibrary.shared().performChanges({
- var assetChangeRequest: PHAssetChangeRequest? = nil
- if isVideo == true {
- assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url)
- } else {
- assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(atFileURL: url)
- }
-
- if let assetPlaceHolder = assetChangeRequest?.placeholderForCreatedAsset {
- if let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.assetCollection) {
- let enumeration: NSArray = [assetPlaceHolder]
- albumChangeRequest.addAssets(enumeration)
- }
- }
- }, completionHandler: { (success, error) in
- if success {
- DDLogNotice(self.successMessage)
- completionHandler(true)
- } else {
- guard let err = error else {
- DDLogError(self.generalError)
- return
- }
- DDLogError(self.writeErrorMessage + "\(err.localizedDescription)")
- completionHandler(false)
- }
- })
- }
- self.checkAuthorizationWithHandler { (authorizationState) in
- if authorizationState == .full {
- if let validAssets = self.assetCollection { // Album already exists
- saveIt(validAssets)
- } else {
- PHPhotoLibrary.shared().performChanges({
- PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: AlbumManager.albumName) // create an asset collection with the album name
- }) { success, error in
- if success, let validAssets = self.fetchAssetCollectionForAlbum() {
- self.assetCollection = validAssets
- saveIt(validAssets)
- } else {
- guard let err = error else {
- DDLogError(self.generalError)
- return
- }
- DDLogError(self.writeErrorMessage + "\(err.localizedDescription)")
- }
- }
- }
- } else if authorizationState == .write || authorizationState == .potentialWrite {
- if isVideo {
- self.saveMovieFromURL(movieURL: url)
- } else {
- guard let data = try? Data(contentsOf: url) else {
- DDLogError(self.writeErrorMessage)
- return
- }
- let image = UIImage(data: data)!
- UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.savedImage), nil)
- }
- } else {
- DDLogNotice(self.permissionNotGrantedMessage)
- }
- }
- }
-
- @objc func saveMovieFromURL(movieURL: URL) {
- if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(movieURL.absoluteString) {
- UISaveVideoAtPathToSavedPhotosAlbum(movieURL.absoluteString, self, #selector(self.savedImage), nil)
- }
- }
-
- @objc func saveMovieToLibrary(movieURL: URL, completionHandler: @escaping ((_ success: Bool) -> Void)) {
- func saveIt(_ validAssets: PHAssetCollection){
- PHPhotoLibrary.shared().performChanges({
-
- if let assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: movieURL) {
- guard let assetPlaceHolder = assetChangeRequest.placeholderForCreatedAsset else {
- DDLogError("Could not create placeholder")
- return
- }
- if let albumChangeRequest = PHAssetCollectionChangeRequest(for: self.assetCollection) {
- let enumeration: NSArray = [assetPlaceHolder]
- albumChangeRequest.addAssets(enumeration)
- }
-
- }
-
- }, completionHandler: { (success, error) in
- if success {
- completionHandler(true)
- DDLogNotice("Successfully saved video to Camera Roll.")
- } else {
- completionHandler(false)
- DDLogError("Error writing to movie library: \(error!.localizedDescription)")
- }
- })
- }
- self.checkAuthorizationWithHandler { (authorizationState) in
- if authorizationState == .full {
- if let validAssets = self.assetCollection { // Album already exists
- saveIt(validAssets)
- } else {
- PHPhotoLibrary.shared().performChanges({
- PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: AlbumManager.albumName) // create an asset collection with the album name
- }) { success, error in
- if success, let validAssets = self.fetchAssetCollectionForAlbum() {
- self.assetCollection = validAssets
- saveIt(validAssets)
- } else {
- guard let err = error else {
- DDLogError(self.generalError)
- return
- }
- DDLogError(self.writeErrorMessage + "\(err.localizedDescription)")
- }
- }
- }
- } else if authorizationState == .write || authorizationState == .potentialWrite {
- self.saveMovieFromURL(movieURL: movieURL)
- } else {
- DDLogNotice(self.permissionNotGrantedMessage)
- }
- }
- }
- }
|