diff --git a/ownCloud.xcodeproj/project.pbxproj b/ownCloud.xcodeproj/project.pbxproj index 310748d0f..238160a52 100644 --- a/ownCloud.xcodeproj/project.pbxproj +++ b/ownCloud.xcodeproj/project.pbxproj @@ -59,6 +59,7 @@ 4C464BF62187AF1500D30602 /* PDFTocItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C464BEE2187AF1500D30602 /* PDFTocItem.swift */; }; 4C6B78102226B83300C5F3DB /* PhotoAlbumTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C6B780F2226B83300C5F3DB /* PhotoAlbumTableViewController.swift */; }; 4C6B78122226B86300C5F3DB /* PhotoAlbumTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C6B78112226B86300C5F3DB /* PhotoAlbumTableViewCell.swift */; }; + 4C80B1E62271BBB400252901 /* PhotoUploadSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C80B1E52271BBB400252901 /* PhotoUploadSection.swift */; }; 4CF8CAB121F9B70600B8CA67 /* UIBarButtonItem+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF8CAB021F9B70500B8CA67 /* UIBarButtonItem+Extension.swift */; }; 5917244E20D3DC2100809B38 /* BiometricalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5917244D20D3DC2100809B38 /* BiometricalTests.swift */; }; 593A821120C7D4C5000E2A90 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 593A821320C7D4C5000E2A90 /* Localizable.strings */; }; @@ -508,6 +509,7 @@ 4C464BEE2187AF1500D30602 /* PDFTocItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PDFTocItem.swift; sourceTree = ""; }; 4C6B780F2226B83300C5F3DB /* PhotoAlbumTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoAlbumTableViewController.swift; sourceTree = ""; }; 4C6B78112226B86300C5F3DB /* PhotoAlbumTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoAlbumTableViewCell.swift; sourceTree = ""; }; + 4C80B1E52271BBB400252901 /* PhotoUploadSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoUploadSection.swift; sourceTree = ""; }; 4CF8CAB021F9B70500B8CA67 /* UIBarButtonItem+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBarButtonItem+Extension.swift"; sourceTree = ""; }; 5917244D20D3DC2100809B38 /* BiometricalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BiometricalTests.swift; sourceTree = ""; }; 593A821220C7D4C5000E2A90 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; lineEnding = 0; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; @@ -1357,6 +1359,7 @@ 233E0FD72099F11D00C3D8D5 /* SecuritySettingsSection.swift */, DC854935218331CF00782BA8 /* UserInterfaceSettingsSection.swift */, 232F7CAC2097140300EE22E4 /* UploadsSettingsSection.swift */, + 4C80B1E52271BBB400252901 /* PhotoUploadSection.swift */, 23957A6C209AFFE8003C8537 /* MoreSettingsSection.swift */, DCF4F1812051A94200189B9A /* GlobalSettingsViewController.swift */, 232F7CAE2097260400EE22E4 /* SettingsViewController.swift */, @@ -1873,6 +1876,7 @@ DC018F8C20A1060A00135198 /* ProgressHUDViewController.swift in Sources */, DC7DBA29207F71D600E7337D /* VectorImage.swift in Sources */, 4C464BF12187AF1500D30602 /* PDFTocTableViewCell.swift in Sources */, + 4C80B1E62271BBB400252901 /* PhotoUploadSection.swift in Sources */, DC1B270C209CF34B004715E1 /* BookmarkViewController.swift in Sources */, DC63208321FCAC1E007EC0A8 /* ClientActivityViewController.swift in Sources */, 23EC775A2137F3DD0032D4E6 /* DisplayHostViewController.swift in Sources */, diff --git a/ownCloud/Client/Actions/Actions+Extensions/UploadPhotosAction.swift b/ownCloud/Client/Actions/Actions+Extensions/UploadPhotosAction.swift index e213284b9..d63719327 100644 --- a/ownCloud/Client/Actions/Actions+Extensions/UploadPhotosAction.swift +++ b/ownCloud/Client/Actions/Actions+Extensions/UploadPhotosAction.swift @@ -96,6 +96,9 @@ class UploadPhotosAction: UploadBaseAction { } func upload(asset:PHAsset) { + + guard let userDefaults = OCAppIdentity.shared.userDefaults else { return } + let ressources = PHAssetResource.assetResources(for: asset) if let ressource = ressources.first, let rootItem = context.items.first { @@ -110,22 +113,45 @@ class UploadPhotosAction: UploadBaseAction { progress.completedUnitCount = Int64(completed * 100) } - let localURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(filename) - self.publish(progress: progress) - PHAssetResourceManager.default().writeData(for: ressource, toFile: localURL, options: options) { (error) in + func finishUpload(_ error:Error?, url:URL) { self.unpublish(progress: progress) - if error == nil { - self.upload(itemURL: localURL, to: rootItem, name: filename, completionHandler: { (_) in + self.upload(itemURL: url, to: rootItem, name: url.lastPathComponent, completionHandler: { (_) in // Delete the temporary asset file - try? FileManager.default.removeItem(at: localURL) + try? FileManager.default.removeItem(at: url) }) } else { progress.cancel() } } + + if ressource.uniformTypeIdentifier == "public.heic" && userDefaults.convertHeic { + // Convert HEIC to JPEG using CoreImage APIs + var imageData = Data() + let localURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(filename).deletingPathExtension().appendingPathExtension("jpg") + + PHAssetResourceManager.default().requestData(for: ressource, options: options, dataReceivedHandler: { (data) in + imageData.append(data) + }, completionHandler: { (error) in + if error == nil { + if let ciImage = CIImage(data: imageData) { + let jpegData = CIContext().jpegRepresentation(of: ciImage, colorSpace: CGColorSpaceCreateDeviceRGB()) + try? jpegData?.write(to: localURL) + } + } + finishUpload(error, url:localURL) + }) + } else { + // No conversion + let localURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(filename) + + PHAssetResourceManager.default().writeData(for: ressource, toFile: localURL, options: options) { (error) in + finishUpload(error, url:localURL) + } + } + } else { self.completed(with: NSError(ocError: .internal)) } diff --git a/ownCloud/Resources/de-DE.lproj/Localizable.strings b/ownCloud/Resources/de-DE.lproj/Localizable.strings index 93f8f90c3..593f627c0 100644 --- a/ownCloud/Resources/de-DE.lproj/Localizable.strings +++ b/ownCloud/Resources/de-DE.lproj/Localizable.strings @@ -253,3 +253,7 @@ "%@ of %@" = "%@ von %@"; "Invalid Page" = "Ungültige Seite"; "The entered page number doesn't exist" = "Die eingegebene Seitennummer existiert nicht"; + +/* Photo upload settings */ +"Photo Upload" = "Fotos hochladen"; +"Convert HEIC to JPEG" = "HEIC in JPEG konvertieren"; diff --git a/ownCloud/Resources/de.lproj/Localizable.strings b/ownCloud/Resources/de.lproj/Localizable.strings index 6d8015cfb..6a7c8869c 100644 --- a/ownCloud/Resources/de.lproj/Localizable.strings +++ b/ownCloud/Resources/de.lproj/Localizable.strings @@ -253,3 +253,7 @@ "%@ of %@" = "%@ von %@"; "Invalid Page" = "Ungültige Seite"; "The entered page number doesn't exist" = "Die angegebene Seitennummer existiert nicht."; + +/* Photo upload settings */ +"Photo Upload" = "Fotos hochladen"; +"Convert HEIC to JPEG" = "HEIC in JPEG konvertieren"; diff --git a/ownCloud/Resources/en.lproj/Localizable.strings b/ownCloud/Resources/en.lproj/Localizable.strings index c19a234ec..07573200a 100644 --- a/ownCloud/Resources/en.lproj/Localizable.strings +++ b/ownCloud/Resources/en.lproj/Localizable.strings @@ -268,3 +268,7 @@ "All Photos" = "All Photos"; "Albums" = "Albums"; "Importing '%@' from photo library" = "Importing '%@' from photo library"; + +/* Photo upload settings */ +"Photo Upload" = "Photo Upload"; +"Convert HEIC to JPEG" = "Convert HEIC to JPEG"; diff --git a/ownCloud/Resources/ru.lproj/Localizable.strings b/ownCloud/Resources/ru.lproj/Localizable.strings index 013d3ab39..8a0657273 100644 --- a/ownCloud/Resources/ru.lproj/Localizable.strings +++ b/ownCloud/Resources/ru.lproj/Localizable.strings @@ -233,3 +233,7 @@ "%@ of %@" = "%@ из %@"; "Invalid Page" = "Неверная страница"; "The entered page number doesn't exist" = "Введённый номер страницы не существует"; + +/* Photo upload settings */ +"Photo Upload" = "Загрузка фото"; +"Convert HEIC to JPEG" = "Конвертировать HEIC в JPEG"; diff --git a/ownCloud/Settings/PhotoUploadSection.swift b/ownCloud/Settings/PhotoUploadSection.swift new file mode 100644 index 000000000..a2f94f027 --- /dev/null +++ b/ownCloud/Settings/PhotoUploadSection.swift @@ -0,0 +1,58 @@ +// +// PhotoUploadSection.swift +// ownCloud +// +// Created by Michael Neuwert on 25.04.2019. +// Copyright © 2019 ownCloud GmbH. All rights reserved. +// + +/* +* Copyright (C) 2018, ownCloud GmbH. +* +* This code is covered by the GNU Public License Version 3. +* +* For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/ +* You should have received a copy of this license along with this program. If not, see . +* +*/ + +import UIKit + +extension UserDefaults { + + enum PhtoUploadKeys : String { + case ConvertHEICtoJPEGKey = "convert-heic-to-jpeg" + } + + public var convertHeic: Bool { + set { + self.set(newValue, forKey: PhtoUploadKeys.ConvertHEICtoJPEGKey.rawValue) + } + + get { + return self.bool(forKey: PhtoUploadKeys.ConvertHEICtoJPEGKey.rawValue) + } + } +} + +class PhotoUploadSettingsSection: SettingsSection { + + private var convertSwitchRow: StaticTableViewRow? + + override init(userDefaults: UserDefaults) { + + super.init(userDefaults: userDefaults) + + self.headerTitle = "Photo Upload".localized + self.identifier = "photo-upload" + + convertSwitchRow = StaticTableViewRow(switchWithAction: { [weak self] (_, sender) in + if let convertSwitch = sender as? UISwitch { + self?.userDefaults.convertHeic = convertSwitch.isOn + } + }, title: "Convert HEIC to JPEG".localized, value: self.userDefaults.convertHeic) + + self.add(row: convertSwitchRow!) + } + +} diff --git a/ownCloud/Settings/SettingsViewController.swift b/ownCloud/Settings/SettingsViewController.swift index 0f8306f92..b8d486fa7 100644 --- a/ownCloud/Settings/SettingsViewController.swift +++ b/ownCloud/Settings/SettingsViewController.swift @@ -20,20 +20,22 @@ import UIKit import ownCloudSDK class SettingsViewController: StaticTableViewController { - - override func viewDidLoad() { - super.viewDidLoad() - - self.navigationItem.title = "Settings".localized - - let userDefaults = OCAppIdentity.shared.userDefaults - - let securitySettings = SecuritySettingsSection(userDefaults: userDefaults!) - let userInterfaceSettings = UserInterfaceSettingsSection(userDefaults: userDefaults!) - let moreSettings = MoreSettingsSection(userDefaults: userDefaults!) - self.addSection(securitySettings) - self.addSection(userInterfaceSettings) - self.addSection(moreSettings) - } - + + override func viewDidLoad() { + super.viewDidLoad() + + self.navigationItem.title = "Settings".localized + + let userDefaults = OCAppIdentity.shared.userDefaults + + let securitySettings = SecuritySettingsSection(userDefaults: userDefaults!) + let userInterfaceSettings = UserInterfaceSettingsSection(userDefaults: userDefaults!) + let photoUploadSettings = PhotoUploadSettingsSection(userDefaults: userDefaults!) + let moreSettings = MoreSettingsSection(userDefaults: userDefaults!) + self.addSection(securitySettings) + self.addSection(userInterfaceSettings) + self.addSection(photoUploadSettings) + self.addSection(moreSettings) + } + }