修改多张照片时只有一个 iOS 权限对话框
Posted
技术标签:
【中文标题】修改多张照片时只有一个 iOS 权限对话框【英文标题】:Only one iOS permission dialog when modifying multiple photos 【发布时间】:2017-02-21 21:00:12 【问题描述】:我的应用程序允许用户从相机胶卷中多选图像并将编辑应用到这些图像。但是,它会提示用户对每个图像编辑的权限。编辑用户图像时是否可以只显示一个权限对话框?如果是,我该如何将我的编辑分组到一个权限中?这是我的应用程序的屏幕截图。
我在应用商店中发现了另一个应用,它只需一个权限提示即可批量删除照片。这是该应用程序的屏幕截图。有谁知道这是否可以用于“修改”而不仅仅是“删除”?
这是我修改每个资产的代码。
func selectImageFromCameraRoll()
let newImagePicker = BSImagePickerViewController()
newImagePicker.doneButton = UIBarButtonItem(title: "Stamp", style: UIBarButtonItemStyle.done, target: self, action: nil)
bs_presentImagePickerController(newImagePicker, animated: true,
select: (asset: PHAsset) -> Void in
print("Selected")
, deselect: (asset: PHAsset) -> Void in
print("Deselected")
, cancel: (assets: [PHAsset]) -> Void in
print("Cancel")
, finish: (assets: [PHAsset]) -> Void in
for asset in assets
self.saveUpdatedAsset(asset: asset)
print("Finished")
, completion: nil)
func saveUpdatedAsset(asset: PHAsset)
let options = PHContentEditingInputRequestOptions()
options.canHandleAdjustmentData = adjustmentData in
print("here")
return adjustmentData.formatIdentifier == self.myIdentifier
var id: PHContentEditingInputRequestID = 0
id = asset.requestContentEditingInput(with: options)
input, info in
guard let input = input else
asset.cancelContentEditingInputRequest(id)
return
let act = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
act.backgroundColor = .darkGray
act.layer.cornerRadius = 3
act.center = self.view.center
self.view.addSubview(act)
act.startAnimating()
DispatchQueue.global(qos: .userInitiated).async
let inurl = input.fullSizeImageURL!
let inorient = input.fullSizeImageOrientation
let output = PHContentEditingOutput(contentEditingInput: input)
let outurl = output.renderedContentURL
guard var ci = CIImage(contentsOf: inurl)?.applyingOrientation(inorient) else
act.removeFromSuperview()
let ac = UIAlertController(title: "Save error", message: "Failed to edit image ????", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
self.present(ac, animated: true)
return
let space = ci.colorSpace!
let uim = UIImage(ciImage: ci)
let width = uim.size.width
let height = uim.size.height
let location = Locations(rawValue: UserDefaults.standard.value(forKey: "location") as! String)!
var point = CGPoint(x: 0, y: 0)
switch location
case .topLeft:
point = CGPoint(x: 30, y: 50)
case .topRight:
point = CGPoint(x: width - 30, y: 50)
case .bottomLeft:
point = CGPoint(x: 30, y: height - 50)
case .bottomRight:
point = CGPoint(x: width - 30, y: height - 50)
case .center:
point = CGPoint(x: width / 2, y: height / 2)
case .topCenter:
point = CGPoint(x: width / 2, y: 50)
case .bottomCenter:
point = CGPoint(x: width / 2, y: height - 50)
let savedFormat = UserDefaults.standard.value(forKey: "format") as! String
var date = Date()
if !self.currentDateBool
date = UserDefaults.standard.value(forKey: "selectedDate") as! Date
let timestampText = getFormattedDateFromFormatType(formatType: savedFormat, date: date) as NSString
let timestampImage = self.textToImage(drawText: timestampText, inImage: uim, atPoint: point)
ci = CIImage(image: timestampImage)!
try! CIContext().writeJPEGRepresentation(of: ci, to: outurl, colorSpace: space)
let data = NSKeyedArchiver.archivedData(withRootObject: timestampText)
output.adjustmentData = PHAdjustmentData(
formatIdentifier: self.myIdentifier, formatVersion: "1.0", data: data)
phphotoLibrary.shared().performChanges(
print("finishing")
typealias Req = PHAssetChangeRequest
let req = Req(for: asset)
req.contentEditingOutput = output
) ok, err in
DispatchQueue.main.async
act.removeFromSuperview()
print("in completion handler")
if ok
print("changed!")
else
print("phasset change request error: \(err)")
【问题讨论】:
@rmaddy 这可能吗?从 Apple 的文档中可以看出:“如果您的应用编辑了照片库中已有资产的内容——包括您的应用最近添加的资产——照片会提示用户更改资产内容的权限。” 没关系。我想到了错误的权限对话框。你说的是删除确认。 您可能需要在一次调用deleteAssets
时删除所有图像
@rmaddy 我正在尝试修改资产。我展示的示例删除屏幕截图是我发现的另一个应用程序,它能够通过一个权限请求删除所有资产。我想知道是否有一种方法可以通过一个权限要求修改多个资产。
一次调用performChanges
即可完成所有更改请求。
【参考方案1】:
@dave-weston 是对的——您需要将这些请求合并到一个 PHPhotoLibrary.performChanges()
块中。
问题是如何 — 我自己也刚刚弄清楚了这一点。我是菜鸟,如果有更好的方法请告诉我。
// Create a dictionary with PHAsset as keys and PHContentEditingOutput as values.
var changeDict: [PHAsset: PHContentEditingOutput] = [:]
// Use two local variables to to the counting work
var _i = 0
let _n = <#YOUR_ARRAY_OF_ASSETS#>.count
// Get dict and perform changes
<#YOUR_ARRAY_OF_ASSETS#>.forEach (asset) in
asset.requestContentEditingInput(with: nil) (optionalInput, info) in
guard let input = optionalInput else return
guard let url = input.fullSizeImageURL else return
// perform the editing operation, which applies a noir filter in this case
let ciImage = CIImage(contentsOf: url, options: nil)!
.oriented(forExifOrientation: input.fullSizeImageOrientation)
// write to output location
let output = PHContentEditingOutput(contentEditingInput: input)
let adjustmentData = PHAdjustmentData(formatIdentifier: "s",
formatVersion: "1.2",
data: "CIPhotoEffectTransfer".data(using: .utf8)!)
output.adjustmentData = adjustmentData
if let data = <#YOUR_CIIMAGE_TO_DATA_METHOD#>
do
try data.write(to: output.renderedContentURL, options: .atomic)
catch
fatalError("Cannot write ciImage to disk.")
changeDict[asset] = output
// Count + 1
_i += 1
// Check if this is the last PHAsset to process. If so, we commit all the changes.
if _i >= _n
// Commit the changes
PHPhotoLibrary.shared().performChanges(
for (asset, output) in changeDict
let request = PHAssetChangeRequest(for: asset)
request.contentEditingOutput = output
, completionHandler: (success, error) in
if success
else
print("Error Saving Edits:", error?.localizedDescription ?? "Unknown Error")
)
这种方法存在一些问题,但目前它对我来说还可以。再次,请让我知道是否有更好的方法,可能会增加对 Grand Central Dispatch 处理流程的控制......目前它只计算所有处理的照片数量,没有任何控制照片的顺序得到处理。
【讨论】:
【参考方案2】:来自PHPhotoLibrary
的文档:
注意
对于
performChanges:completionHandler:
或performChangesAndWait:error:
方法的每次调用,“照片”都会显示一条警报,询问用户是否允许编辑照片库的内容。如果您的应用需要一次提交多个更改,请将它们合并到一个更改块中。...
要编辑多张现有照片的内容,请创建多个
PHAssetChangeRequest
对象并将每个contentEditingOutput
属性设置为独立的PHContentEditingOutput
对象。
https://developer.apple.com/reference/photos/phphotolibrary
【讨论】:
感谢您的回复。我正在努力解决如何创建多个 PHAssetChangeRequest 对象并将每个对象的 contentEditingOutput 属性设置为独立的 PHContentEditingOutput 对象。对此有何建议?【参考方案3】:比我想象的要容易得多,我也在找同样的问题:
PHPhotoLibrary.shared().performChanges(
PHAssetChangeRequest.deleteAssets(your_array_of_assets as NSFastEnumeration)
) (success, error) in
【讨论】:
那是删除。我要做的是修改以上是关于修改多张照片时只有一个 iOS 权限对话框的主要内容,如果未能解决你的问题,请参考以下文章