I need some Help regarding Phonegap plugins:
First , i have a JS File which invoke the native code using the phonegap.exec() containing the result handler function, error handler function , a reference to the native class's name and native function name as well as an array of parameters . My question is : if it is possible to invoke the function (native method) with given specified parameters?
That means : in my phonegap plugin file (.h & .m)
1- can i specify the arguments and their Types (NSInteger, NSString) like java
void myMethod(int a , string b){}
-(void) myMethod:(NSMutableArray )arguments withDict:(NSMutableDictionary)options;
Or is it as specified by Phonegap or Objective C ?
2- And what does it withDict means in this case ??
3- can i addicate this?
4- Why should my Code looks like this ?
-(void)myMethod: (NSMutableArray*)arguments withDict:(NSMutableDictionary*)options {
NSString *callbackID =[arguments pop];
NSString *myParam = #"";
NSArray *arrayArguments = [[arguments objectAtIndex:0] componentsSeparatedByString:#"|"];
NSString *stringArgument = ([arArguments objectAtIndex:0]);
I want to invoke my method like this :
why shall i put my arguments (as a String array element) then take it out , split it to get the right element from the String )?
Many Thanks for helping
Ok here's how you do it… The example I've added in below is a implementation of the Email plugin in Phonegap, with multiple strings. You can always substitute my string code to identify NSNumbers, or any other kind of arguments.
In JS ::
First I create the arguments with their values. . .
var attachmentData = {};
attachmentData.data = userData;
attachmentData.fileName = fileName;
var mailData = {};
mailData.toRecipients = "";
mailData.subject = "Exporting Backup for user data";
mailData.body = "User data for application. Please find the attachment containing the data from the last week.";
nativeMail(attachmentData, mailData);
Now we call a function that packages all this data for a Phonegap Plugin and sends it to the plugin class
function nativeMail(attachmentData, mailData){
e_args = {};
if(mailData.toRecipients)
e_args.toRecipients = mailData.toRecipients;
if(mailData.subject)
e_args.subject = mailData.subject; //"Hello World";
if(mailData.body)
e_args.body = mailData.body;
//call to phonegap plugin for native mail iOS
e_args.attachmentFileName = attachmentData.fileName;
e_args.datatoattach = attachmentData.data;
cordova.exec(null, fail, "EmailComposer", "showEmailComposer", [e_args]);
}
Now the EmailComposer.h file
- (void) showEmailComposer:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
And finally, how to take these arguments from the Mutablle Dictionary/Array and retrieve our string values.
- (void) showEmailComposer:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
NSString* toRecipientsString = [options valueForKey:#"toRecipients"];
NSString* ccRecipientsString = [options valueForKey:#"ccRecipients"];
NSString* bccRecipientsString = [options valueForKey:#"bccRecipients"];
NSString* subject = [options valueForKey:#"subject"];
NSString* body = [options valueForKey:#"body"];
NSString* isHTML = [options valueForKey:#"bIsHTML"];
. . . . . .
}
This is the only way to go about it. Its to do with the way that Phonegap itself handles data to be passed from your javascript web app to the native class. It cannot be changed. The MutableDictionary or the MutableArray will handle any kind of data you need it to. There are no limitations. However, the passing of this data can only be done using the format above. Once you have the options and arguments in the .m class, you are free to retrieve them or parse them into the data type you need.
Related
Our project is supposed to re-use existing Adapters that expect JSON objects as input parameters into the Adapter procedures.
When we try to call the Adapter using:
WLProcedureInvocationData *myInvocationData = [[WLProcedureInvocationData alloc] initWithAdapterName:#"UserProfileAdapter" procedureName:#"getUserProfile"];
myInvocationData.parameters = [NSArray arrayWithObjects:#"{\"userEmail\" : \"xxx#xxx.com\"}", nil];
then the input object that is passed to the Adapter procedure is not a Javascript object, but a javascript string.
In order to make a object out of it, we would always need to parse the input from a string to an object using:
input = JSON.parse(input);
since we are reusing existing code that is in production with a hybrid app, this is not an option, since with the hyrbid app this works fine.
How can we pass JSON to a Javascript adapter so that the Adapter automatically creates an input object and not a string?
The answer we found was for Swift and for Android ... did not try ObjC anymore.
iOS:
//Create JSON Object with keys and values
let jsonObject: [String: AnyObject] = [
"userName": "xxx#xxx.com",
"password": "12345"
]
let procedureData = WLProcedureInvocationData(adapterName: "AuthAdapter", procedureName: "login")
procedureData.parameters = [jsonObject]
Android:
JSONObject jsonObj = new JSONObject("\"userName\":\"xxx#xx.com\",\"password\":\"1234\"}");
Object[] params = new Object[]{jsonObj};
WLProcedureInvocationData invocationData = new WLProcedureInvocationData("AuthAdapter", "login");
invocationData.setParameters(params);
We have not tried anything with deeper nested JSON structures yet and this might still be troublesome, but for a basic JSON this works fine for us now.
Good evening,
I'm currently trying to produce a list of all available serial ports in Swift using the ORSSerialPort Objective-C library. The current code is below, this just generates the NSArray that contains the available ports.
import Foundation
import Cocoa
class Serial {
init() {
}
#IBOutlet var serialListPullDown : NSPopUpButton!
func refreshSerialList(defaultprompt: String) {
//Initialize ORSSerialPortManager
let portManager : ORSSerialPortManager = ORSSerialPortManager.sharedSerialPortManager()
var availablePorts : NSArray = portManager.availablePorts
//Erase entries from popup field
serialListPullDown?.removeAllItems()
}
}
Currently, when I insert a breakpoint at:
var availablePorts : NSArray = portManager.availablePorts
When I work through the debug window (http://imgur.com/NcXnJig) I see that I can find the path I'm looking for, in this case '/dev/cu.Bluetooth-Modem'. However this information seems to be hidden behind _path which should be a variable of the ORSSerialPortManager class but I cannot find it in the source files. Obviously the information is there, but how do I get to it in my Swift function?
availablePorts is an NSArray of ORSSerialPort objects. It looks like you can directly access the path property to get the data you're looking for.
var availablePorts : NSArray = portManager.availablePorts
for port in availablePorts as [ORSSerialPort] {
println("Serial Port: \(port.path)");
}
I am making a simple app where the user can create severals objects which are saved with CoreData.
My problem is, I want each object to have an image linked to it. The image is brought by the iphone camera or the user personal Camera roll, so the images will have a pretty high weight (> 1MB each I think).
I read that when the weight of images is that high, the good way to handle this is to save the images in the documentsDirectory folder, and save the path to coreData. I achieved this pretty easily.
But how do I find a path name for the image to be linked to an unique object? CoreData does not really handle unique IDs, and two objects can have the same name... I searched around objectID but it's not working really good and I'm not sure it's the good way to handle this.
Do you have any idea? Is there an other simple way I am totally missing? Thank you in advance.
use coredata's objectID as identifier
id uri = [self sanitizeFilename:coreDataObject.objectID.URIRepresentation];
[NSString stringWithFormat:#"%#.png", uri];
helper sanitizeFilename:
- (NSString *)sanitizeFileNameString:(NSString *)fileName {
NSCharacterSet* illegalFileNameCharacters = [NSCharacterSet characterSetWithCharactersInString:#"/\\?%*|\"<>"];
return [[fileName componentsSeparatedByCharactersInSet:illegalFileNameCharacters] componentsJoinedByString:#""];
}
Just create an object_id number property in your CoreData model entity description and each time a new object is created increment this property by one and assign it to the object, then use a naming convention like
[NSString stringWithFormat:#"object_%d_img.png", idNumber];
And save it to NSDoctumentsDirectory.
Then in object's - (void)prepareForDeletion method delete the image.
As for how to increment the id value, create a method that will fetch an object with biggest id value - simply get all objects with sort descriptor by id desc and use it + 1 when creating a new entity.
Thanks to #Daij-Djan. I created version for Swift:
var itemObjectId:String = item.objectID.URIRepresentation().absoluteString!
var fileName = NSString(format:"%#.png", FileHelper.sanitizeFileNameString(itemObjectId)) as String
Helper for sanitize:
struct FileHelper {
static func sanitizeFileNameString(fileName:String) ->String {
let illegalFileNameCharacters:NSCharacterSet = NSCharacterSet(charactersInString: "/\\?%*|\"<>")
let components : [String] = fileName.componentsSeparatedByCharactersInSet(illegalFileNameCharacters)
let joinedString = join("", components)
return joinedString
}
}
I think you'll need to generate the unique id by your self. Since a user can have several objects. so maybe the image id could be named as such
userId-objectId-somesalt
save the value to the object's path
I am using Titanium. and I want to make Titanium Module (for iOS).
every thing is working fine. But, how i retrieve data in xCode whose i send through .js file.
in .js file
var data = "Mritunjay";
var oldData = "Singh";
var data = module_tset.findData({"newData":data,"oldData":oldData});
in xCode
-(id)findData:(NSMutableArray *)args
{
NSMutableArray *ary = [[NSMutableArray alloc]initWithArray:args];
// How i retrieve "newData" Value in xCode?
}
please help me..! thanks
First you should check the documentation for this.
Also, check the example moddevguide projects on GitHub, they have very simple and straightforward examples of how to do this.
In a nutshell heres the code to extract those arguments (assuming you setup this correctly).
-(id)findData:(id)args
{
ENSURE_SINGLE_ARG(args,NSDictionary); // Standard practice
NSString *newData_Pass = [TiUtils stringValue:[args objectForKey:#"newData"]];
// Now do something with newData!
}
Thats it!
In my -request:didLoad: delegate method I'm NSLoging the results but I can't figure out what's the content?
It looks like result is an NSArray but what is inside it? how do I parse the data?
A sample of the log looks like this:
result: (
{
"fql_result_set" = (
{
uid2 = 1234567;
},
{
uid2 = 12345678;
}
);
name = queryID;
},
{
"fql_result_set" = (
{
"birthday_date" = "05/12/1987";
name = "John Doe";
},
{
"birthday_date" = "03/01/1978";
name = "Jane Doe";
}
);
name = queryBirthday;
}
)
The Facebook iOS tutorial, in "Step 6: Using the Graph API", says
Note that the server response will be in JSON string format. The SDK uses an open source JSON library https://github.com/stig/json-framework/ to parse the result. If a parsing error occurs, the SDK will callback request:didFailWithError: in your delegate.
A successful request will callback request:didLoad: in your delegate. The result passed to your delegate can be an NSArray, if there are multiple results, or an NSDictionary if there is only a single result.
In your example, everything printed by NSLog inside "()" is part of an NSArray, while everything inside "{}" (which also have keys incidentally) is part of an NSDictionary and therefore accessible by key (name).
http://developers.facebook.com/docs/mobile/ios/build/
According to https://developers.facebook.com/docs/reference/api/, all 'responses' are JSON-Objects. To parse these, iOS 5 provides a class called NSJSONSerialization (NSJSONSerialization Class Reference)
You normally parse it as follows:
NSDictionary *dictionaryJSON = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];