在应用程序被杀死后请求使用通过 UIImagePickerController 选取的视频文件的权限
Requesting permission to use a video file that is picked with UIImagePickerController after app is killed
所以我目前正在使用 UIImagePickerController 从图库中挑选视频。我有这个代码:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL {
MediaManager.shared.sourceType = picker.sourceType
self.metadata.videoURL = videoURL
...
}
else if let asset = info[UIImagePickerController.InfoKey.phAsset] as? PHAsset {
asset.getURL(completionHandler: { url in
self.metadata.videoURL = url
...
})
}
else if let ref = info[UIImagePickerController.InfoKey.phAsset] as? URL {
self.metadata.videoURL = ref
...
}
else {
...
}
}
因此,我保存了视频 url 并基于此 url 我能够获取视频数据等
问题是,下次我重新启动应用程序时,我希望能够在不使用选择器的情况下再次获取该视频。但似乎我没有权限。有什么方法可以向 iOS 请求许可,即使我关闭了应用程序(或者它崩溃了),我也可以通过它的 url 打开视频?
编辑:
例如,我得到这样的东西 url:
file:///private/var/mobile/Containers/Data/Application/AC5AD743-924F-430D-9C34-F3848E4CEE75/tmp/4CBAD829-8764-4234-BCCF-BFA571845D55.MOV
但是应用被kill后我真的不能用了。那么如何用picker挑选东西,以后再用呢
Important: Although they are safe to use while your app is running, file reference URLs are not safe to store and reuse between launches of your app because a file’s ID may change if the system is rebooted. If you want to store the location of a file persistently between launches of your app, create a bookmark as described in Locating Files Using Bookmarks.
所以我建议使用 bookmarkData(options:includingResourceValuesForKeys:relativeTo:) 方法为现有 URL 创建书签。
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
guard let mediaType = info[.mediaType] as? String,
mediaType == kUTTypeMovie as String,
let url = info[.mediaURL] as? URL else {
return
}
do {
let bookmarkData = try url.bookmarkData()
UserDefaults.standard.set(bookmarkData, forKey: "mediaURL")
} catch {
print("bookmarkData error: \(error)")
}
}
func mediaURL() -> URL? {
guard let urlData = UserDefaults.standard.data(forKey: "mediaURL") else {
return nil
}
var staleData = false
let mediaURL = try? URL(resolvingBookmarkData: urlData, options: .withoutUI, relativeTo: nil, bookmarkDataIsStale: &staleData)
return staleData ? nil : mediaURL
}
改编@Michcio 的回答,你可以这样做:
Select 视频事件:
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
let mediaType = info[UIImagePickerController.InfoKey.mediaType] as AnyObject
if mediaType as! String == kUTTypeMovie as String {
guard let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL else {
return
}
let bookmarkData: Data
do {
try bookmarkData = videoURL.bookmarkData()
let userDefaults = UserDefaults.standard
userDefaults.set(bookmarkData, forKey: "video")
userDefaults.synchronize()
} catch {
print(error)
}
self.pickerController.dismiss(animated: true, completion: nil)
}
}
重启后恢复视频URL:
func getVideo() {
let userDefaults = UserDefaults.standard
guard let decoded = userDefaults.data(forKey: "video") else {
return
}
var videoURL: NSURL
do {
var isSSNField = ObjCBool(true)
try videoURL = NSURL.init(resolvingBookmarkData: decoded, options: .withoutUI, relativeTo: nil, bookmarkDataIsStale: &isSSNField)
print(videoURL)
} catch {
print(error)
}
}
所以我目前正在使用 UIImagePickerController 从图库中挑选视频。我有这个代码:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL {
MediaManager.shared.sourceType = picker.sourceType
self.metadata.videoURL = videoURL
...
}
else if let asset = info[UIImagePickerController.InfoKey.phAsset] as? PHAsset {
asset.getURL(completionHandler: { url in
self.metadata.videoURL = url
...
})
}
else if let ref = info[UIImagePickerController.InfoKey.phAsset] as? URL {
self.metadata.videoURL = ref
...
}
else {
...
}
}
因此,我保存了视频 url 并基于此 url 我能够获取视频数据等
问题是,下次我重新启动应用程序时,我希望能够在不使用选择器的情况下再次获取该视频。但似乎我没有权限。有什么方法可以向 iOS 请求许可,即使我关闭了应用程序(或者它崩溃了),我也可以通过它的 url 打开视频?
编辑:
例如,我得到这样的东西 url:
file:///private/var/mobile/Containers/Data/Application/AC5AD743-924F-430D-9C34-F3848E4CEE75/tmp/4CBAD829-8764-4234-BCCF-BFA571845D55.MOV
但是应用被kill后我真的不能用了。那么如何用picker挑选东西,以后再用呢
Important: Although they are safe to use while your app is running, file reference URLs are not safe to store and reuse between launches of your app because a file’s ID may change if the system is rebooted. If you want to store the location of a file persistently between launches of your app, create a bookmark as described in Locating Files Using Bookmarks.
所以我建议使用 bookmarkData(options:includingResourceValuesForKeys:relativeTo:) 方法为现有 URL 创建书签。
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
guard let mediaType = info[.mediaType] as? String,
mediaType == kUTTypeMovie as String,
let url = info[.mediaURL] as? URL else {
return
}
do {
let bookmarkData = try url.bookmarkData()
UserDefaults.standard.set(bookmarkData, forKey: "mediaURL")
} catch {
print("bookmarkData error: \(error)")
}
}
func mediaURL() -> URL? {
guard let urlData = UserDefaults.standard.data(forKey: "mediaURL") else {
return nil
}
var staleData = false
let mediaURL = try? URL(resolvingBookmarkData: urlData, options: .withoutUI, relativeTo: nil, bookmarkDataIsStale: &staleData)
return staleData ? nil : mediaURL
}
改编@Michcio 的回答,你可以这样做:
Select 视频事件:
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
let mediaType = info[UIImagePickerController.InfoKey.mediaType] as AnyObject
if mediaType as! String == kUTTypeMovie as String {
guard let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL else {
return
}
let bookmarkData: Data
do {
try bookmarkData = videoURL.bookmarkData()
let userDefaults = UserDefaults.standard
userDefaults.set(bookmarkData, forKey: "video")
userDefaults.synchronize()
} catch {
print(error)
}
self.pickerController.dismiss(animated: true, completion: nil)
}
}
重启后恢复视频URL:
func getVideo() {
let userDefaults = UserDefaults.standard
guard let decoded = userDefaults.data(forKey: "video") else {
return
}
var videoURL: NSURL
do {
var isSSNField = ObjCBool(true)
try videoURL = NSURL.init(resolvingBookmarkData: decoded, options: .withoutUI, relativeTo: nil, bookmarkDataIsStale: &isSSNField)
print(videoURL)
} catch {
print(error)
}
}