Skip to content

Instantly share code, notes, and snippets.

@ha1f
Created October 14, 2020 08:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ha1f/6b8adf6b24a92f72471e53fc7c91b6d7 to your computer and use it in GitHub Desktop.
Save ha1f/6b8adf6b24a92f72471e53fc7c91b6d7 to your computer and use it in GitHub Desktop.
extension Reactive where Base: UIImagePickerController {
static func createAndPresent(from parent: UIViewController?, animated: Bool = true, configureImagePicker: @escaping (UIImagePickerController) throws -> Void = { x in }) -> Observable<[UIImagePickerController.InfoKey: Any]> {
return Observable.create { [weak parent] observer in
let imagePicker = UIImagePickerController()
let dismissDisposable = imagePicker.rx
.didCancel
.subscribe(onNext: { [weak imagePicker] _ in
guard let imagePicker = imagePicker else {
return
}
dismissViewController(imagePicker, animated: animated)
})
let eventDisposable = imagePicker.rx.didFinishPickingMediaWithInfo
.subscribe(onNext: { [weak imagePicker] info in
guard let imagePicker = imagePicker else {
return
}
observer.on(.next(info))
dismissViewController(imagePicker, animated: animated)
})
do {
try configureImagePicker(imagePicker)
} catch {
observer.on(.error(error))
return Disposables.create()
}
guard let parent = parent else {
observer.on(.completed)
return Disposables.create()
}
parent.present(imagePicker, animated: animated, completion: nil)
return Disposables.create(dismissDisposable, eventDisposable, Disposables.create {
dismissViewController(imagePicker, animated: animated)
})
}
}
}
let movieType = kUTTypeMovie as String
guard UIImagePickerController.isSourceTypeAvailable(.camera),
let availableMediaTypes = UIImagePickerController.availableMediaTypes(for: .camera),
availableMediaTypes.contains(movieType) else {
return
}
let recordMovie = UIImagePickerController.rx.createAndPresent(from: self, animated: true) { (picker) in
picker.sourceType = .camera
picker.mediaTypes = [movieType]
picker.allowsEditing = true
picker.videoMaximumDuration = 60 // 上限60秒
picker.videoQuality = .typeHigh
}
recordMovie
.flatMap { info -> Observable<URL> in
if let phAsset = info[.phAsset] as? PHAsset {
let fileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("/copied.mp4")
let imageManager = PHImageManager.default()
return imageManager.rx.requestAsset(asset: phAsset)
.flatMap { asset -> Observable<URL> in
switch asset {
case let .movie(movieAsset):
return MovieService().saveAsMp4(movieAsset, nil, saveTo: fileURL)
.map { _ in fileURL }
.asObservable()
case .image:
return .empty()
}
}
} else if let url = info[.mediaURL] as? URL {
return .just(url)
}
// error
return .empty()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment