feat: add photo library permission checking

This commit is contained in:
CMK 2021-05-06 15:05:24 +08:00
parent 597fc3fa1a
commit 51c01066d3
7 changed files with 71 additions and 6 deletions

View File

@ -27,6 +27,10 @@
"title": "Sign out",
"message": "Are you sure you want to sign out?",
"confirm": "Sign Out"
},
"save_photo_failure": {
"title": "Save Photo Failure",
"message": "Please enable photo libaray access permission to save photo."
}
},
"controls": {
@ -55,7 +59,8 @@
"find_people": "Find people to follow",
"manually_search": "Manually search instead",
"skip": "Skip",
"report_user": "Report %s"
"report_user": "Report %s",
"settings": "Settings"
},
"status": {
"user_reblogged": "%s reblogged",
@ -411,4 +416,4 @@
"text_placeholder": "Type or paste additional comments"
}
}
}
}

View File

@ -31,6 +31,12 @@ internal enum L10n {
/// Publish Failure
internal static let title = L10n.tr("Localizable", "Common.Alerts.PublishPostFailure.Title")
}
internal enum SavePhotoFailure {
/// Please enable photo libaray access permission to save photo.
internal static let message = L10n.tr("Localizable", "Common.Alerts.SavePhotoFailure.Message")
/// Save Photo Failure
internal static let title = L10n.tr("Localizable", "Common.Alerts.SavePhotoFailure.Title")
}
internal enum ServerError {
/// Server Error
internal static let title = L10n.tr("Localizable", "Common.Alerts.ServerError.Title")
@ -94,6 +100,8 @@ internal enum L10n {
internal static let savePhoto = L10n.tr("Localizable", "Common.Controls.Actions.SavePhoto")
/// See More
internal static let seeMore = L10n.tr("Localizable", "Common.Controls.Actions.SeeMore")
/// Settings
internal static let settings = L10n.tr("Localizable", "Common.Controls.Actions.Settings")
/// Share
internal static let share = L10n.tr("Localizable", "Common.Controls.Actions.Share")
/// Share %@

View File

@ -171,8 +171,18 @@ extension StatusTableViewCellDelegate where Self: StatusProvider {
guard let attachment = attachment, let url = URL(string: attachment.url) else { return nil }
return self.context.photoLibraryService.saveImage(url: url)
}
.sink(receiveCompletion: { _ in
// do nothing
.switchToLatest()
.sink(receiveCompletion: { [weak self] completion in
guard let self = self else { return }
switch completion {
case .failure(let error):
guard let error = error as? PhotoLibraryService.PhotoLibraryError,
case .noPermission = error else { return }
let alertController = SettingService.openSettingsAlertController(title: L10n.Common.Alerts.SavePhotoFailure.title, message: L10n.Common.Alerts.SavePhotoFailure.message)
self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil))
case .finished:
break
}
}, receiveValue: { _ in
// do nothing
})

View File

@ -5,6 +5,8 @@
"Common.Alerts.PublishPostFailure.Message" = "Failed to publish the post.
Please check your internet connection.";
"Common.Alerts.PublishPostFailure.Title" = "Publish Failure";
"Common.Alerts.SavePhotoFailure.Message" = "Please enable photo libaray access permission to save photo.";
"Common.Alerts.SavePhotoFailure.Title" = "Save Photo Failure";
"Common.Alerts.ServerError.Title" = "Server Error";
"Common.Alerts.SignOut.Confirm" = "Sign Out";
"Common.Alerts.SignOut.Message" = "Are you sure you want to sign out?";
@ -30,6 +32,7 @@ Please check your internet connection.";
"Common.Controls.Actions.Save" = "Save";
"Common.Controls.Actions.SavePhoto" = "Save photo";
"Common.Controls.Actions.SeeMore" = "See More";
"Common.Controls.Actions.Settings" = "Settings";
"Common.Controls.Actions.Share" = "Share";
"Common.Controls.Actions.ShareUser" = "Share %@";
"Common.Controls.Actions.SignIn" = "Sign In";

View File

@ -208,8 +208,17 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate {
switch viewController.viewModel.item {
case .status(let meta):
context.photoLibraryService.saveImage(url: meta.url)
.sink { _ in
// do nothing
.sink { [weak self] completion in
guard let self = self else { return }
switch completion {
case .failure(let error):
guard let error = error as? PhotoLibraryService.PhotoLibraryError,
case .noPermission = error else { return }
let alertController = SettingService.openSettingsAlertController(title: L10n.Common.Alerts.SavePhotoFailure.title, message: L10n.Common.Alerts.SavePhotoFailure.message)
self.coordinator.present(scene: .alertController(alertController: alertController), from: self, transition: .alertController(animated: true, completion: nil))
case .finished:
break
}
} receiveValue: { _ in
// do nothing
}

View File

@ -8,12 +8,21 @@
import os.log
import UIKit
import Combine
import Photos
import AlamofireImage
final class PhotoLibraryService: NSObject {
}
extension PhotoLibraryService {
enum PhotoLibraryError: Error {
case noPermission
}
}
extension PhotoLibraryService {
func saveImage(url: URL) -> AnyPublisher<UIImage, Error> {
@ -21,6 +30,11 @@ extension PhotoLibraryService {
let notificationFeedbackGenerator = UINotificationFeedbackGenerator()
return Future<UIImage, Error> { promise in
guard PHPhotoLibrary.authorizationStatus(for: .addOnly) != .denied else {
promise(.failure(PhotoLibraryError.noPermission))
return
}
ImageDownloader.default.download(URLRequest(url: url), completion: { [weak self] response in
guard let self = self else { return }
switch response.result {

View File

@ -171,3 +171,19 @@ final class SettingService {
}
}
extension SettingService {
static func openSettingsAlertController(title: String, message: String) -> UIAlertController {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let settingAction = UIAlertAction(title: L10n.Common.Controls.Actions.settings, style: .default) { _ in
guard let url = URL(string: UIApplication.openSettingsURLString) else { return }
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
alertController.addAction(settingAction)
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil)
alertController.addAction(cancelAction)
return alertController
}
}