Using UIKIT ImagePicker

I’m trying to work out how to use UIImagePickerController to select a picture from the user’s library, to see if it works better than Xojo’s ImagePicker implementation.

In the IOSKit example app, there is an example of video recording, but I cannot work out how to modify it to return a simple image

I tried this


var picker as  UIKit.UIImagePickerController = new UIKit.UIImagePickerController
picker.sourceType = UIKit.UIImagePickerController.Source.PhotoLibrary
picker.mediaTypes = Foundation.NSArray.CreateWithObject(new NSString(UIKit.UIImagePickerController.kUTTypeImage))
picker.PresentInView(Canvaspicker)

That last line wants an iOSView… most objects in my project are Mobilennnn objects
I added an object and set it’s type to be iOSView, but I cannot get a picker to show up.

Does anyone have a worked example I could follow?

You can modify the code to accept a MobileView instead of iOSView without any issues

IOSKIt (the copy I have) is still full of IOSViews
I have swapped them for MobileScreen (MobileView doesnt seem to exist)

The image list appears, I can tap on a picture.
But I cannot get beyond that.

My code is now:

var mypick as  UIKit.UIImagePickerController = new UIKit.UIImagePickerController
AddHandler mypick.picturetaken, AddressOf HandlePictureTaken //do I need this?

mypick.sourceType = UIKit.UIImagePickerController.Source.PhotoLibrary
mypick.mediaTypes = Foundation.NSArray.CreateWithObject(new NSString(UIKit.UIImagePickerController.kUTTypeImage))

mypick.PresentInView(thedesigner)

if mypick.originalImage <> nil then
  var ww as integer = 1
end if

I get this dialog- I can tap an image but there is no ‘use what I tapped’ button, only ‘Cancel’

As soon as I tap on an image, It hit a nil object exception in this method:

and I SUSPECT that it is an invalid PID, (but nothing here is debuggable, as it is all pointers)

which brings me back to ‘does anyone have a working example’? :slight_smile:

First of all,

That line that says

If w<>nil then

Should say

If w <> nil and w.value <> nil then

That said, I’m concerned about the use of the WeakRef there. I think what’s happening is that the controller is being destroyed immediately, not giving you time to grab that pointer again. But it’s 4am and I don’t have this code in front of me.

Yeah. I don’t know what that bit of code is there for, or doing, is part of the problem.
Not my code, it’s in the iOSKit
(Which is always the issue with ‘copy and paste’ coding, of which I am normally a critic.)

I’m going to suggest you try the fork that Jérémie Leroy and I have going which is updated for API2 and has numerous fixes, including this one.

If anyone cares…

The way this works in xojo code is that you create an obj-c class to represent the delegate which handles the callbacks that come from iOS, in this case, either that the user picked something or that they clicked Cancel. An instance of this class is created and stored with a reference to the class instance that it belongs to. The easiest way to do this is to use a Dictionary where the key is the deluge and the value is the instance of the parent class.

When the callback occurs, you get the specified parameters plus two other pieces of information. Let’s take “imagePickerController:didFinishPickingMediaWithInfo:” as an example. That callback says that it takes two parameters… the controller and the info (the parts that are followed by a colon.

The delegate callback gets back:

  1. A pointer to the delegate class > The Sender
  2. A pointer to the selector > imagePickerController:didFinishPickingMediaWithInfo:
  3. A pointer to the controller > a UIImagePickerController
  4. A pointer to the info > an NSDictionary

Now we could loop through all of the instances of the controller that we have instantiated to figure out which controller is the right one, but since the delegate instances are unique to their parent classes, we can just look it up in the dictionary I talked about above. If it exists in the dictionary then you can operate on it and raise events.

There were two issues that I saw in the original class. The first was the WeakRef. I understand why people like using them for this, but it’s not what Apple intended. you need to hold onto a reference of the controller as long as you need it to be in existence and the WeakRef actually lets it go out of scope earlier than it should.

The second piece is that the delegate is not being retained. Whenever you create an object with Init where the API doesn’t otherwise indicate that the object will be returned as already “retained” you need to do it yourself.

I did these two things for this class and the NilObjectException is gone.

2 Likes

I do. Can’t say I immediately understand, but two things strike me here.

One: well done you!
Two: Nothing Apple creates is straightforward.

Thanks Greg.
I can now open images two ways - either by using
iCloud.UIDocumentPickerViewController

or

UIKit.UIImagePickerController

if I use UIDocumentPickerViewController , I don’t see Photos, just images that happen to be in iCloud

If I use UIImagePickerController, I get Photos, but many of them are in the wrong orientation, although they report the correct height and width.

Using MBS plugins, if I load such an image into GMImageMBS and call AutoOrient (which works on desktop), nothing is changed.
Why is the image rotated, how might i fix this?

As far as I can tell, the returned UIImage should have an imageOrientation property, but this is not exposed in Xojo