This is a migrated thread and some comments may be shown as answers.

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

4 Answers 180 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Wei
Top achievements
Rank 2
Wei asked on 08 Mar 2015, 03:46 PM
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?





4 Answers, 1 is accepted

Sort by
0
Jason Zhekov
Telerik team
answered on 09 Mar 2015, 09:38 AM
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.

 
0
Wei
Top achievements
Rank 2
answered on 09 Mar 2015, 10:30 AM
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
0
Jason Zhekov
Telerik team
answered on 09 Mar 2015, 11:18 AM
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.

 
0
Wei
Top achievements
Rank 2
answered on 09 Mar 2015, 03:28 PM
Hi Jason, thanks, it works.
Tags
General Discussions
Asked by
Wei
Top achievements
Rank 2
Answers by
Jason Zhekov
Telerik team
Wei
Top achievements
Rank 2
Share this question
or