Skip to content

Commit

Permalink
fix: Use PHPicker API for sensor image selection #2128 (#2145)
Browse files Browse the repository at this point in the history
  • Loading branch information
priyonto authored Sep 4, 2024
1 parent 28a5c65 commit 4ffbf30
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import MobileCoreServices
import PhotosUI
import RuuviCore
import RuuviPresenters
import UIKit
Expand All @@ -9,7 +9,7 @@ class PhotoPickerPresenterSheet: NSObject, PhotoPickerPresenter {
var permissionPresenter: PermissionPresenter!

func showLibrary() {
checkPhotoLibraryPermission()
showPhotoLibrary()
}

func showCameraUI() {
Expand All @@ -33,22 +33,33 @@ extension PhotoPickerPresenterSheet: UIImagePickerControllerDelegate, UINavigati
}
}

// MARK: - Private
// MARK: - PHPickerViewControllerDelegate

extension PhotoPickerPresenterSheet {
private func checkPhotoLibraryPermission() {
if permissionsManager.isPhotoLibraryPermissionGranted {
showPhotoLibrary()
} else {
permissionsManager.requestPhotoLibraryPermission { [weak self] granted in
if granted {
self?.showPhotoLibrary()
} else {
self?.permissionPresenter.presentNoPhotoLibraryPermission()
extension PhotoPickerPresenterSheet: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: { [weak self] in
guard let sSelf = self else { return }
guard let result = results.first else { return }

if result.itemProvider.canLoadObject(ofClass: UIImage.self) {
result.itemProvider.loadObject(ofClass: UIImage.self) { (object, error) in
guard error == nil else {
return
}
if let image = object as? UIImage {
DispatchQueue.main.async {
sSelf.delegate?.photoPicker(presenter: sSelf, didPick: image)
}
}
}
}
}
})
}
}

// MARK: - Private

extension PhotoPickerPresenterSheet {

private func checkCameraPermission() {
if permissionsManager.isCameraPermissionGranted {
Expand All @@ -66,10 +77,18 @@ extension PhotoPickerPresenterSheet {

private func showPhotoLibrary() {
guard let viewController = UIApplication.shared.topViewController() else { return }
let vc = UIImagePickerController()
vc.sourceType = .photoLibrary
vc.delegate = self
viewController.present(vc, animated: true)
presentPhotoPicker(from: viewController)
}

private func presentPhotoPicker(from viewController: UIViewController) {
var configuration = PHPickerConfiguration()
configuration.filter = .images
configuration.selectionLimit = 1
configuration.preferredAssetRepresentationMode = .current

let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
viewController.present(picker, animated: true, completion: nil)
}

private func showCamera() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ public protocol RuuviLocalImages {
func setBackground(_ id: Int, for identifier: Identifier)
func setNextDefaultBackground(for identifier: Identifier) -> UIImage?
func getCustomBackground(for identifier: Identifier) -> UIImage?
func setCustomBackground(image: UIImage, for identifier: Identifier) -> Future<URL, RuuviLocalError>
func setCustomBackground(
image: UIImage,
compressionQuality: CGFloat,
for identifier: Identifier
) -> Future<
URL,
RuuviLocalError
>
func deleteCustomBackground(for uuid: Identifier)

func backgroundUploadProgress(for identifier: Identifier) -> Double?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ class ImagePersistenceDocuments: ImagePersistence {
try? FileManager.default.removeItem(at: url)
}

func persistBg(image: UIImage, for identifier: Identifier) -> Future<URL, RuuviLocalError> {
func persistBg(
image: UIImage,
compressionQuality: CGFloat,
for identifier: Identifier
) -> Future<URL, RuuviLocalError> {
let uuid = identifier.value
let promise = Promise<URL, RuuviLocalError>()
DispatchQueue.global().async {
if let data = image.jpegData(compressionQuality: 1.0) {
if let data = image.jpegData(compressionQuality: compressionQuality) {
do {
let url = try self.getBgDirectory().appendingPathComponent(uuid + self.ext)
try data.write(to: url)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ import UIKit
protocol ImagePersistence {
func fetchBg(for identifier: Identifier) -> UIImage?
func deleteBgIfExists(for identifier: Identifier)
func persistBg(image: UIImage, for identifier: Identifier) -> Future<URL, RuuviLocalError>
func persistBg(
image: UIImage,
compressionQuality: CGFloat,
for identifier: Identifier
) -> Future<URL, RuuviLocalError>
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,17 @@ final class RuuviLocalImagesUserDefaults: RuuviLocalImages {
}
}

func setCustomBackground(image: UIImage, for identifier: Identifier) -> Future<URL, RuuviLocalError> {
func setCustomBackground(
image: UIImage,
compressionQuality: CGFloat,
for identifier: Identifier
) -> Future<URL, RuuviLocalError> {
let promise = Promise<URL, RuuviLocalError>()
let persist = imagePersistence.persistBg(image: image, for: identifier)
let persist = imagePersistence.persistBg(
image: image,
compressionQuality: compressionQuality,
for: identifier
)
persist.on(success: { url in
self.setBackground(0, for: identifier)
let userInfoKey: BPDidChangeBackgroundKey
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,23 @@ public final class RuuviServiceCloudSyncImpl: RuuviServiceCloudSync {
}
URLSession
.shared
.dataTask(with: pictureUrl, completionHandler: { data, _, error in
.dataTask(with: pictureUrl,
completionHandler: {
data,
_,
error in
if let error {
promise.fail(error: .networking(error))
} else if let data {
if let image = UIImage(data: data) {
// Sync the image with original quality from cloud
DispatchQueue.main.async {
self.ruuviLocalImages
.setCustomBackground(image: image, for: sensor.id.mac)
.setCustomBackground(
image: image,
compressionQuality: 1.0,
for: sensor.id.mac
)
.on(success: { fileUrl in
self.ruuviLocalImages.setPictureIsCached(for: sensor)
promise.succeed(value: fileUrl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ extension RuuviServiceOwnershipImpl {
macId: MACIdentifier
) {
if let customImage = localImages.getCustomBackground(for: macId) {
// Send the original custom image to cloud. The resize and compression
// is already handled at the time of setting it to local.
if let jpegData = customImage.jpegData(compressionQuality: 1.0) {
let remote = cloud.upload(
imageData: jpegData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,34 @@ public final class RuuviServiceSensorPropertiesImpl: RuuviServiceSensorPropertie
},
for: mac
)
local = localImages.setCustomBackground(image: image, for: mac)
local = localImages.setCustomBackground(
image: croppedImage,
compressionQuality: compressionQuality,
for: mac
)
} else if let luid {
local = localImages.setCustomBackground(image: image, for: luid)
local = localImages.setCustomBackground(
image: croppedImage,
compressionQuality: compressionQuality,
for: luid
)
} else {
promise.fail(error: .bothLuidAndMacAreNil)
return promise.future
}
} else {
if let mac = macId {
local = localImages.setCustomBackground(image: image, for: mac)
local = localImages.setCustomBackground(
image: croppedImage,
compressionQuality: compressionQuality,
for: mac
)
} else if let luid {
local = localImages.setCustomBackground(image: image, for: luid)
local = localImages.setCustomBackground(
image: croppedImage,
compressionQuality: compressionQuality,
for: luid
)
} else {
promise.fail(error: .bothLuidAndMacAreNil)
return promise.future
Expand Down

0 comments on commit 4ffbf30

Please sign in to comment.