How to use FunctionReference as parameters of interop.types.selector

Thread is closed for posting
5 posts, 0 answers
  1. Wei
    Wei avatar
    8 posts
    Member since:
    Jun 2013

    Posted 08 Mar 2015 Link to this post

    Hi

    I'm implementing NativeScript to be able to save an image to the Album,  currently the Android part is complete and I'm struggle to make the iOS version work.

    I'm trying to call UIImageWriteToSavedPhotosAlbum as

    var functionReference = new interop.FunctionReference(function(result) {
         result.success = true;
    });

    UIImageWriteToSavedPhotosAlbum(data, instance, interop.types.selector(interop.handleof(functionReference)), null);

    But it doesn't work, so I had look in to the tests of the ios-runtime tests/NativeScriptTests/NativeScriptTests/app/Marshalling/FunctionPointerTests.js and noticed that it called a function namely functionWithSimpleFunctionPointer which is an objective c function.

    Is there any way I can avoid any objective c and to make UIImageWriteToSavedPhotosAlbum working?





  2. Jason Zhekov
    Admin
    Jason Zhekov avatar
    3 posts

    Posted 09 Mar 2015 Link to this post

    Hi,

    The UIImageWriteToSavedPhotosAlbum function doesn't take a function pointer, but an Objective-C object and a selector:
    You can read more about this pattern in the Target-Action section in the Apple docs.

    // Adds a photo to the saved photos album.  The optional completionSelector should have the form:
    //  - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
    void UIImageWriteToSavedPhotosAlbum(UIImage *image, id completionTarget, SEL completionSelector, void *contextInfo);


    Here is an example of this API in use: stackoverflow. And here is the same written in NativeScript:

    var CompletionTarget = NSObject.extend({
      "thisImage:hasBeenSavedInPhotoAlbumWithError:usingContextInfo:": function(image, error, context) {
        if (error) {
          // Do anything needed to handle the error or display it to the user
        } else {
          // .... do anything you want here to handle
          // .... when the image has been saved in the photo album
        }
      }
    }, {
      exposedMethods: {
        "thisImage:hasBeenSavedInPhotoAlbumWithError:usingContextInfo:": {
          returns: interop.types.void,
          params: [UIImage, NSError, interop.Pointer]
        }
      }
    });
     
    var completionTarget = CompletionTarget.new();
     
    UIImageWriteToSavedPhotosAlbum(theImage, completionTarget, "thisImage:hasBeenSavedInPhotoAlbumWithError:usingContextInfo:", null);


    The syntax at the moment is quite cumbersome, but is working correctly and we are discussing ways to redesign it in the future.

    Please let me know in case I can assist you with something else. Thanks!

    Regards,
    Jason Zhekov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. Wei
    Wei avatar
    8 posts
    Member since:
    Jun 2013

    Posted 09 Mar 2015 in reply to Jason Zhekov Link to this post

    Hi Jason, thanks a lot for your reply, I tried the code above and still getting 

    [NSConcreteMutableData CGImage]: unrecognized selector sent to instance 0x7ab67eb0
    *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteMutableData CGImage]: unrecognized selector sent to instance 0x7ab67eb0'

    Is it because the code is not parsing selector as parameter?

    the variable "theImage" is returned from UIImageJPEGRepresentation

    I also tried 

    UIImageWriteToSavedPhotosAlbum(theImage, completionTarget, interop.types.selector("thisImage:hasBeenSavedInPhotoAlbumWithError:usingContextInfo:"), null);


    It doesn't work either
  4. Jason Zhekov
    Admin
    Jason Zhekov avatar
    3 posts

    Posted 09 Mar 2015 Link to this post

    Hi,

    I don't think that the problem is with the selector marshalling. You must pass plain JavaScript strings where a selector is expected. You can read more about this in selector marshalling from our docs.

    The problem here is that theImage is NSData*, but the UIImageWriteToSavedPhotosAlbum function is expecting UIImage*. So if you remove the UIImageJPEGRepresentation call and pass the UIImage directly it should be working properly.

    I hope this solves your problem.


    Regards,
    Jason Zhekov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  5. Wei
    Wei avatar
    8 posts
    Member since:
    Jun 2013

    Posted 09 Mar 2015 in reply to Jason Zhekov Link to this post

    Hi Jason, thanks, it works.
Back to Top