Swift ImagePickerController didFinishPickingMediaWithInfo not fired
The correct delegate method of UIImagePickerControllerDelegate
in Swift 3 for imagePickerController(_:didFinishPickingMediaWithInfo:)
is as follow.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
}
You can check Apple Documentations on UIImagePickerControllerDelegate
for more details.
didFinishPickingMediaWithInfo not being called for UIImagePickerControllerDelegate
I fixed this by using:
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
dismiss(animated: false) {
self.uploadProfileImage(image: image)
}
}
else {
dismiss(animated: false) {
}
}
}
I am unsure why my imagePickerController Coordinator is not triggering didFinishPickingMediaWithInfo
You need to assign delegate unconditionally, but you assign it only if sourceType
is not nil.
Here is fixed part
func makeUIViewController(context: Context) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
if let type = self.sourceType {
imagePicker.sourceType = type
// probably this line also should be moved out of condition
imagePicker.mediaTypes = ["public.image", "public.movie"] // << ??
}
imagePicker.delegate = context.coordinator // << this one !!
return imagePicker
}
imagePickerController - didFinishPickingMediaWithInfo does not get called after picking media
It appears as though the function declaration changed between Swift 3 and 4.2. This mustn't have been updated for you by the Swift Migrator Tool. One trick I do when this happens, to check what the correct function declaration is, is to use multiline comment syntax to comment out your current function (didFinishPickingMediaWithInfo
in your case). Then you can start typing the function out again, and use Xcode autocomplete to ensure you have it correct. You can then copy the contents of the function you commented out to this new and correct function declaration.
Or - you could just look it up the documentation! According to the documentation on imagePickerController, the function should be declared as:
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
If you replace your function declaration with the above, it should get called again.
UIImagePickerController delegate is not being called
The problem is this declaration:
private func imagePickerController(
_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
You have declared this method private
, so Objective-C has no way of knowing that it exists. Thus, it can't call into it.
Basically, Cocoa looks to see whether this method is implemented, discovers that it isn't (because you've hidden it), and gives up. There's no visible penalty, because this delegate method is optional, and when it is not implemented, Cocoa dismisses the picker for you when the user is finished with it.
So just delete private
and you should be good to go. This exposes the delegate method to Objective-C, and so it will be called.
(You do not have to say @objc
to expose it to Objective-C, as you would if this were your own function, because you've declared we adopt UIImagePickerControllerDelegate, which is an Objective-C protocol.)
UIImagePickerControllerDelegate not called
The problem is in the following code snippet:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let image = info[UIImagePickerControllerEditedImage] as? UIImage else {
return
}
completion(image)
picker.dismiss(animated: true, completion: nil)
}
You are expecting that there is always an edited image, which may not be the case for all photos in your photo library. Try using the UIImagePickerControllerOriginalImage
key instead when info[UIImagePickerControllerEditedImage]
returns nil
.
If these methods aren't called in the first place, you need to make sure you have a strong reference to the ImagePickerService
instance.
For example, this code works:
class ViewController: UIViewController {
var picker: ImagePickerService?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { [weak self] in
guard let `self` = self else { return }
self.picker = ImagePickerService() { (image) in
print(image)
}
self.picker?.show(from: self)
}
}
}
Related Topics
How to Obtain the Selected Text from the Frontmost Application in MACos
Can't Programmatically Change Color Set in Storyboard as Color from Xcassets Catalog
Downloading and Caching Images from Url Asynchronously
Ambiguous Reference to Member 'Tableview'
Checking for Nil Value in Swift Dictionary Extension
How to Use Generic Types to Get Object with Same Type
How to Get the File Creation Date Using Url Resourcevalues Method in Swift 3
Swiftui: Can't Get the Transition of a Detailview to a Zstack in the Mainview to Work
Apply a Shadow on a Uiview That Have Same Corner Radius Than View
Why Isn't Guard Let Foo = Foo Valid
Xcode 9 and Xcode 10 Giving Different Results, Even with Same Swift Version
Swift Setter Causing Exc_Bad_Access
Swift Dictionary Default Value
How to Animate a Model's Rotation in Realitykit
Uitableviewautomaticdimension Not Working for Resizing Cell Height
Iboutlet of Another View Controller Is Nil