How to access iOS photo library / use Objective-C properly?

Hi there,

using UE 4.6.1 on Windows, I have a code project and am packaging it for iOS.

I was wondering whether it is possible to access / communicate with the iOS Photo library / app or with the camera, as I want the user to pick a picture in game. Unfortunately I didn’t find anything about that.

Would I have to write an iOS plugin or could I use a library or framework which does that? Do I have to develop on a Mac, using XCode to be able to do that?

Is there any information about it?

So, I can use Objective-C code when wrapped around with the preprocessor tag

#if PLATFORM_IOS
    // objc code
#endif

What I need to have is something like this camera app, where, after the click of a UMG button, the Photo Library would pop up so that a user can pick a photo. Seems like I need a ViewController for this but I don’t know how to properly implement it so that my button click executes the ObjC code and stuff.

Some hints or even a general direction would be really nice.

I figured out how to achieve this. For everyone interested, here is the code:

MyViewController.h

#pragma once

#if PLATFORM_IOS
#import <UIKit/UIKit.h>

// UIImagePickerControllerDelegate to respond to user interactions
// UINavigationControllerDelegate because we want to present the photo library modally
@interface MyViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

// function to run in iOS main thread
+ (void) runSelectPhoto;

@end
#endif

MyViewController.cpp

// ...

#if PLATFORM_IOS
#include "IOSAppDelegate.h"
#import <Foundation/Foundation.h>
#endif

#include "MyViewController.h"

#if PLATFORM_IOS

@interface MyViewController()
@end

@implementation MyViewController

+ (MyViewController*)GetDelegate
{
    static MyViewController * Singleton = [[MyViewController alloc] init];
    return Singleton;
}

-(void)selectPhoto
{
    // create the Photo Library display object
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    // type of picker interface to be displayed by the controller
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    // delegate object which receives notification when the user picks an image or exits the picker interface
    picker.delegate = self;
    // show object
    // the UIImagePickerController is ONLY supported in portrait mode (see http://stackoverflow.com/a/16346664/4228316)
    [[IOSAppDelegate GetDelegate].IOSController presentViewController : picker animated : NO completion : nil];
}

+(void)runSelectPhoto
{
    // perform this action on the iOS main thread
    [[MyViewController GetDelegate] performSelectorOnMainThread:@selector(selectPhoto) withObject:nil waitUntilDone : NO];
}

#pragma mark - Image Picker Controller delegate methods

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo : (NSDictionary *)info{

    // get the chosen original image
    UIImage *chosenImage = info[UIImagePickerControllerOriginalImage];
    // ...

    // call C++ functions on the game thread
    [FIOSAsyncTask CreateTaskWithBlock : ^ bool(void)
    {
        // call C++ functions
        // ...
        return true;
    }];

    // get rid of UIImagePicker
    [picker dismissViewControllerAnimated : YES completion : NULL];
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [picker dismissViewControllerAnimated : YES completion : NULL];
}

@end
#endif

The method to show the image picker is called with

#if PLATFORM_IOS
	NSLog(@"Show image picker");
	[MyViewController runSelectPhoto];
#endif

Sorry to bump this up?
Can I use this methodology only in the source code version of UE4, or in the Launcher version as well? Can I then expose some function in blueprints?

u have a sample for android devices?

It should work i think, you need source code to modify engine or build it in custom configuration that laucher does not provide

I was wondering if this conversation is still the state of the art? Seems like a nice feature to wrap up cross platform and add to the engine.

Another question - are your files above in your project or at the engine level? I have a couple of small iOS features to implement in objective C but would like to stay clear of engine modifications as far as possible.

Thanks for posting the code btw - VERY helpful :slight_smile:

Well blow me down I just slapped it in cpp / h files in my project and it just worked ™.

Thanks again!

hi guys~i no a programmer ,can you guys teach me you to activate it? can show some step~thank you

I used this code in 4.15 and was able to build and deploy to my iOS 10 device. However, whenever the “runSelectPhoto” method is executed the app crashes.

I’ve got the proper permissions in the pList file (NSPhotoLibraryUsageDescription) and the app requests permission correctly (which I allow).

EDIT: The crash is caused because the photo library requires the app be in portrait mode. If you change your app to run in portrait mode (Project Settings->iOS->Orientation) You have to select Support Portrait Orientation and deselect Landscape Left/Right.

Hey guys:

Very helpful. Thanks for the info and the check in 4.15!

If you think this would work in the launcher version of UE4, can you describe steps of how to integrate the cpp and .h file into a new project? For instance, where to store these files and how to access them from the editor?

Thanks!

Hi,
It’s my first project working for iOS with UE4(4.17.2) - I see your code and dude, thank you for the clear explanation. However there is a detail is not that clear to me: Can I just write this code block inside a C++ function?
#if PLATFORM_IOS
NSLog(@“Show image picker”);
[MyViewController runSelectPhoto];
#endif
So far, I compiled the class and it was successful, but I was wondering about how to call the functions wrote with ObjectiveC

Hi. I’m un-sure how to use the resultant UIImage object. The end-result I’m looking for is to have a UE4 Texture that I can assign to an image.

UIImage *chosenImage = info[UIImagePickerControllerOriginalImage]; Want to be able to convert this to a UE4 Texture.

Any help on this is appreciated. Thanks.