Video picker delegate doesn't fire method

ios

#1

Hi,
I was calling the native video picker using this stackoverflow answer i.e https://stackoverflow.com/a/10531752/859968. I have successfully present video picker. But when i select video, i don’t see any event fire.
Here is my code:

    presentVideoPicker() {
        let imagePicker = UIImagePickerController.new();
        let delegate = UIImagePickerControllerDelegateImp.new();

        imagePicker.delegate = delegate;
        imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary;
        imagePicker.mediaTypes = NSArray.arrayWithObject(<string>kUTTypeMovie);
        let appWindow = UIApplication.sharedApplication.keyWindow;
        appWindow.rootViewController.presentModalViewControllerAnimated(imagePicker, true);
    }
export class UIImagePickerControllerDelegateImp extends NSObject implements UIImagePickerControllerDelegate {
    static ObjCProtocols = [UIImagePickerControllerDelegate];

    static new(): UIImagePickerControllerDelegateImp {
        return <UIImagePickerControllerDelegateImp> super.new();
    }

       imagePickerControllerDidFinishPickingMediaWithInfo?(
        picker: UIImagePickerController, info: NSDictionary<string, any>) {
            console.log('imagePickerControllerDidFinishPickingMediaWithInfo');
    }

    imagePickerControllerDidFinishPickingImageEditingInfo?(
        picker: UIImagePickerController, image: UIImage, editingInfo: NSDictionary<string, any>): void {
            console.log('imagePickerControllerDidFinishPickingImageEditingInfo');
    }

    imagePickerControllerDidCancel?(picker: UIImagePickerController): void {
        console.log('imagePickerControllerDidCancel');
    }
}

Edit:
It turns out that it works after trying few times. i am not sure why…Sometimes it works on the 2nd try and sometimes after several tries.


#2

I guess it’s garbage collection problem, JavaScript doesn’t know whether not you are using something in native class. You will always have to store a JS reference when you are using a native object, if you don’t do so, garbage collector will clean it up soon therefore your native object no longer exists.

Try placing imagePicker and delegate variable in global scope of that file, nullify them when you are done using them.


#3

Hi @manojdcoder indeed you were right. I moved everything to separate file and made it work like below:

import * as utils from 'tns-core-modules/utils/utils';

export class VideoPicker {
    _imagePickerController: UIImagePickerController;
    _imagePickerControllerDelegate: UIImagePickerControllerDelegateImp;
    
    constructor() {
        this._imagePickerControllerDelegate = new UIImagePickerControllerDelegateImp();
        // let delegate = UIImagePickerControllerDelegateImp.new();

        let imagePickerController = UIImagePickerController.new();
        imagePickerController.delegate = this._imagePickerControllerDelegate;
        imagePickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary;
        imagePickerController.mediaTypes = NSArray.arrayWithObject(<string>kUTTypeMovie);

        this._imagePickerController = imagePickerController;
    }

    present() {
        return new Promise((resolve, reject) => {
            this._imagePickerControllerDelegate._resolve = resolve;
            // let appWindow = UIApplication.sharedApplication.keyWindow;
            // appWindow.rootViewController.presentModalViewControllerAnimated(imagePicker, true);
            
            let app = utils.ios.getter(UIApplication, UIApplication.sharedApplication);
            app.keyWindow.rootViewController.presentModalViewControllerAnimated(this._imagePickerController, true);
        });
    }
}


export class UIImagePickerControllerDelegateImp extends NSObject implements UIImagePickerControllerDelegate {
    public static ObjCProtocols = [UIImagePickerControllerDelegate];

    _resolve: any;

    static new(): UIImagePickerControllerDelegateImp {
        return <UIImagePickerControllerDelegateImp> super.new();
    }

    imagePickerControllerDidFinishPickingMediaWithInfo?(
        picker: UIImagePickerController, info: NSDictionary<string, any>) {
            console.log('imagePickerControllerDidFinishPickingMediaWithInfo');
            let videoUrl: NSURL = info.objectForKey(UIImagePickerControllerMediaURL);
            let path = videoUrl.path;

            this._resolve({ name: videoUrl.lastPathComponent, path: path });
            picker.dismissModalViewControllerAnimated(true);
    }

    imagePickerControllerDidFinishPickingImageEditingInfo?(
        picker: UIImagePickerController, image: UIImage, editingInfo: NSDictionary<string, any>): void {
            console.log('imagePickerControllerDidFinishPickingImageEditingInfo');
    }

    imagePickerControllerDidCancel?(picker: UIImagePickerController): void {
        console.log('imagePickerControllerDidCancel');
        this._resolve();
        picker.dismissModalViewControllerAnimated(true);
    }
}