Skip to content

Commit aa98680

Browse files
committed
Support pick video from ImagePicker
1 parent dac9ffa commit aa98680

File tree

9 files changed

+266
-145
lines changed

9 files changed

+266
-145
lines changed

Example/Source/MessageViewController.swift

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ class MessageViewController: ChatViewController {
9292

9393
imagePickerHelper?.takeOrChoosePhoto()
9494
}
95+
96+
override func didSelectVideo(url: URL?) {
97+
print("URL \(url!)")
98+
}
99+
100+
override func didSelectImage(url: URL?) {
101+
print("URL \(url!)")
102+
}
95103
}
96104

97105
extension MessageViewController {
@@ -155,19 +163,7 @@ extension MessageViewController {
155163
}
156164

157165
private func bindViewModel() {
158-
/// Image Picker Result closure
159-
imagePickerView?.pickImageResult = { image, url, error in
160-
if error != nil {
161-
return
162-
}
163-
164-
guard let _ = image, let _ = url else {
165-
return
166-
}
167-
168-
print("Pick image successfully")
169-
}
170-
166+
171167
}
172168

173169
private func setupData() {
@@ -247,18 +243,3 @@ extension MessageViewController {
247243
tableView.endUpdates()
248244
}
249245
}
250-
251-
extension ChatViewController: ImagePickerHelperResultDelegate {
252-
253-
public func didFinishPickingMediaWithInfo(_ image: UIImage?, _ imagePath: URL?, _ error: Error?) {
254-
if error != nil {
255-
return
256-
}
257-
258-
guard let _ = image, let _ = imagePath else {
259-
return
260-
}
261-
262-
print("Pick image successfully")
263-
}
264-
}

Example/iOS Example.xcodeproj/project.pbxproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -522,14 +522,14 @@
522522
buildSettings = {
523523
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
524524
CODE_SIGN_IDENTITY = "iPhone Developer";
525-
CODE_SIGN_STYLE = Manual;
526-
DEVELOPMENT_TEAM = "";
525+
CODE_SIGN_STYLE = Automatic;
526+
DEVELOPMENT_TEAM = BZ938KC628;
527527
INFOPLIST_FILE = "$(SRCROOT)/Resources/Info.plist";
528528
LD_RUNPATH_SEARCH_PATHS = (
529529
"$(inherited)",
530530
"@executable_path/Frameworks",
531531
);
532-
PRODUCT_BUNDLE_IDENTIFIER = "org.toprating.iOS-Example";
532+
PRODUCT_BUNDLE_IDENTIFIER = org.toprating.iOSExample;
533533
PRODUCT_NAME = "$(TARGET_NAME)";
534534
PROVISIONING_PROFILE_SPECIFIER = "";
535535
SWIFT_VERSION = 4.2;
@@ -543,14 +543,14 @@
543543
buildSettings = {
544544
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
545545
CODE_SIGN_IDENTITY = "iPhone Developer";
546-
CODE_SIGN_STYLE = Manual;
547-
DEVELOPMENT_TEAM = "";
546+
CODE_SIGN_STYLE = Automatic;
547+
DEVELOPMENT_TEAM = BZ938KC628;
548548
INFOPLIST_FILE = "$(SRCROOT)/Resources/Info.plist";
549549
LD_RUNPATH_SEARCH_PATHS = (
550550
"$(inherited)",
551551
"@executable_path/Frameworks",
552552
);
553-
PRODUCT_BUNDLE_IDENTIFIER = "org.toprating.iOS-Example";
553+
PRODUCT_BUNDLE_IDENTIFIER = org.toprating.iOSExample;
554554
PRODUCT_NAME = "$(TARGET_NAME)";
555555
PROVISIONING_PROFILE_SPECIFIER = "";
556556
SWIFT_VERSION = 4.2;

Source/Core/ChatViewController+Subviews.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ extension ChatViewController {
175175
func initImagePickerView() {
176176
imagePickerView = ImagePickerView()
177177
imagePickerView!.isHidden = true
178+
imagePickerView!.pickerDelegate = self
178179
imagePickerView!.parentViewController = self
179180
imagePickerView!.translatesAutoresizingMaskIntoConstraints = false
180181
view.addSubview(imagePickerView!)

Source/Core/ChatViewController.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public enum KeyboardType {
1414
case none
1515
}
1616

17-
open class ChatViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextViewDelegate {
17+
open class ChatViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextViewDelegate, ImagePickerResultDelegate {
1818

1919
open var minimumChatBarHeight: CGFloat = 50
2020
open var customKeyboardHeight: CGFloat = 0
@@ -311,6 +311,14 @@ open class ChatViewController: UIViewController, UITableViewDataSource, UITableV
311311
return true
312312
}
313313

314+
open func didSelectImage(url: URL?) {
315+
316+
}
317+
318+
open func didSelectVideo(url: URL?) {
319+
320+
}
321+
314322
deinit {
315323
removeObserverKeyboardEvents()
316324
}

Source/ImagePicker/ImagePickerCollectionView.swift

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@
99
import UIKit
1010
import Photos
1111

12-
@objc protocol ImagePickerCollectionViewDelegate {
13-
@objc optional func didSelectImage(with localIdentifer: String)
12+
/// Image picker result
13+
@objc public protocol ImagePickerResultDelegate {
14+
@objc optional func didSelectImage(url: URL?)
15+
@objc optional func didSelectVideo(url: URL?)
1416
}
1517

1618
public final class ImagePickerCollectionView: UICollectionView {
1719

1820
var takePhoto: (() -> ())?
1921
var showCollection: (() -> ())?
2022

21-
weak var pickerDelegate: ImagePickerCollectionViewDelegate?
23+
weak var pickerDelegate: ImagePickerResultDelegate?
2224

2325
fileprivate var nColumns = 1
2426
fileprivate var spacing: CGFloat = 2
@@ -120,11 +122,29 @@ extension ImagePickerCollectionView: UICollectionViewDataSource {
120122
}
121123

122124
public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
123-
photoDataManager.requestImage(for: indexPath) { (image, indexPath) in
124-
guard let image = image else { return }
125-
guard let cell = collectionView.cellForItem(at: indexPath) as? ImagePickerCollectionCell else { return }
126-
127-
cell.imageView.image = image
125+
guard let asset = photoDataManager.getAsset(for: indexPath) else {
126+
return
127+
}
128+
129+
DispatchQueue.main.async {
130+
self.photoDataManager.requestImage(for: asset, at: indexPath) { (image, indexPath) in
131+
guard let image = image else { return }
132+
guard let cell = collectionView.cellForItem(at: indexPath) as? ImagePickerCollectionCell else { return }
133+
134+
cell.imageView.image = image
135+
}
136+
}
137+
138+
switch asset.mediaType {
139+
case .video:
140+
DispatchQueue.main.async {
141+
MediaProcesser.getVideoLength(videoAsset: asset) { (length, error) in
142+
if let videoLength = length {
143+
print("Video length = \(videoLength)")
144+
}
145+
}
146+
}
147+
default: break
128148
}
129149
}
130150

@@ -152,10 +172,22 @@ extension ImagePickerCollectionView: UICollectionViewDelegateFlowLayout {
152172

153173
extension ImagePickerCollectionView: UICollectionViewDelegate {
154174

155-
private func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
156-
let localIdentifer = photoDataManager.photoIdentifier(for: indexPath.row)
157-
158-
pickerDelegate?.didSelectImage?(with: localIdentifer)
175+
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
176+
guard let asset = photoDataManager.getAsset(for: indexPath) else {
177+
return
178+
}
179+
180+
switch asset.mediaType {
181+
case .video:
182+
MediaProcesser.storeVideoToURL(videoAsset: asset) { [weak self] (url, error) in
183+
self?.pickerDelegate?.didSelectVideo?(url: url)
184+
}
185+
case .image:
186+
MediaProcesser.storeImage(imageAsset: asset) { [weak self] (url, error) in
187+
self?.pickerDelegate?.didSelectImage?(url: url)
188+
}
189+
default: break
190+
}
159191
}
160192

161193
}
@@ -187,13 +219,13 @@ extension ImagePickerCollectionView {
187219

188220
extension ImagePickerCollectionView: PhotoDataManagerDelegate {
189221

190-
func photoDataManagerDidUpdate() {
222+
public func photoDataManagerDidUpdate() {
191223
performBatchUpdates({ [weak self] in
192224
self?.reloadSections(IndexSet(integer: 0))
193225
}, completion: nil)
194226
}
195227

196-
func targetSize(for indexPath: IndexPath) -> CGSize {
228+
public func targetSize(for indexPath: IndexPath) -> CGSize {
197229
let cell = cellForItem(at: indexPath)
198230
let height = cell?.bounds.size.height ?? bounds.height
199231
return CGSize(width: height * UIScreen.main.scale,

Source/ImagePicker/ImagePickerHelper.swift

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
import UIKit
10+
import MobileCoreServices
1011

1112
/// Protocol use to specify standard for ImagePickerHelper
1213
public protocol ImagePickerHelperable {
@@ -18,21 +19,17 @@ public protocol ImagePickerHelperable {
1819
func accessLibrary()
1920
}
2021

21-
/// Image picker result
22-
public protocol ImagePickerHelperResultDelegate {
23-
func didFinishPickingMediaWithInfo(_ image: UIImage?, _ imagePath: URL?, _ error: Error?)
24-
}
25-
2622
public class ImagePickerHelper: NSObject, ImagePickerHelperable, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
2723

2824
public weak var parentViewController: UIViewController?
29-
public var delegate: ImagePickerHelperResultDelegate?
25+
public weak var delegate: ImagePickerResultDelegate?
3026

3127
public func accessPhoto(from sourceType: UIImagePickerController.SourceType) {
3228
let imagePicker = UIImagePickerController()
3329
imagePicker.delegate = self
3430
imagePicker.allowsEditing = false
3531
imagePicker.sourceType = sourceType
32+
imagePicker.mediaTypes = [kUTTypeImage as String, kUTTypeMovie as String]
3633

3734
parentViewController?.present(imagePicker, animated: true, completion: nil)
3835
}
@@ -60,18 +57,34 @@ public class ImagePickerHelper: NSObject, ImagePickerHelperable, UIImagePickerCo
6057
picker.dismiss(animated: true, completion: nil)
6158
}
6259

63-
DispatchQueue.global(qos: .userInitiated).async {
60+
let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! CFString
61+
switch mediaType {
62+
case kUTTypeImage:
6463
guard let originalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
6564
return
6665
}
67-
68-
originalImage.storeToTemporaryDirectory(completion: { [weak self] (imagePath, error) in
69-
if error != nil {
70-
self?.delegate?.didFinishPickingMediaWithInfo(nil, nil, error!)
66+
if #available(iOS 11.0, *) {
67+
guard let imagePath = info[UIImagePickerController.InfoKey.imageURL] as? String else {
7168
return
7269
}
73-
self?.delegate?.didFinishPickingMediaWithInfo(originalImage, imagePath!, nil)
74-
})
70+
delegate?.didSelectImage?(url: URL(string: imagePath))
71+
} else {
72+
DispatchQueue.main.async {
73+
originalImage.storeToTemporaryDirectory(completion: { [weak self] (imagePath, error) in
74+
guard let imageURL = imagePath else {
75+
return
76+
}
77+
self?.delegate?.didSelectImage?(url: imageURL)
78+
})
79+
}
80+
}
81+
82+
case kUTTypeMovie:
83+
guard let videoPath = info[UIImagePickerController.InfoKey.mediaURL] as? String else {
84+
return
85+
}
86+
delegate?.didSelectVideo?(url: URL(string: videoPath))
87+
default: break
7588
}
7689
}
7790

@@ -86,4 +99,5 @@ public class ImagePickerHelper: NSObject, ImagePickerHelperable, UIImagePickerCo
8699
accessPhoto(from: .photoLibrary)
87100
}
88101
}
102+
89103
}

Source/ImagePicker/ImagePickerView.swift

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ open class ImagePickerView: UIView {
1919
return imagePickerHelper
2020
}()
2121

22-
public var pickImageResult: ((_ image: UIImage?, _ imagePath: URL?, _ error: Error?) -> ())?
23-
2422
public var collectionView: ImagePickerCollectionView!
2523

24+
public weak var pickerDelegate: ImagePickerResultDelegate?
25+
2626
/// Parent View Controller
2727
weak var parentViewController: UIViewController? {
2828
didSet {
@@ -75,32 +75,13 @@ open class ImagePickerView: UIView {
7575
}
7676
}
7777

78-
extension ImagePickerView: ImagePickerCollectionViewDelegate {
79-
80-
func didSelectImage(with localIdentifer: String) {
81-
guard let asset = PhotoDataManager.fetchAsset(with: localIdentifer) else { return }
82-
83-
PhotoDataManager.requestImage(with: asset) { [weak self] image in
84-
DispatchQueue.global().async {
85-
image?.storeToTemporaryDirectory(completion: { (imagePath, error) in
86-
if error != nil {
87-
self?.pickImageResult?(nil, nil, error!)
88-
return
89-
}
90-
self?.pickImageResult?(image, imagePath!, nil)
91-
})
92-
}
93-
}
78+
extension ImagePickerView: ImagePickerResultDelegate {
79+
80+
public func didSelectImage(url: URL?) {
81+
pickerDelegate?.didSelectImage?(url: url)
9482
}
95-
}
96-
97-
extension ImagePickerView: ImagePickerHelperResultDelegate {
9883

99-
public func didFinishPickingMediaWithInfo(_ image: UIImage?, _ imagePath: URL?, _ error: Error?) {
100-
if error != nil {
101-
pickImageResult?(nil, nil, error!)
102-
return
103-
}
104-
pickImageResult?(image, imagePath!, nil)
84+
public func didSelectVideo(url: URL?) {
85+
pickerDelegate?.didSelectVideo?(url: url)
10586
}
10687
}

0 commit comments

Comments
 (0)