JavaScriptCore and Objective C problems - javascript

I'm trying to use the following javascript library with JavasScriptCode in iOS: javascript library
I'm reading it with the following code and everything looks great!
self.jsContext = [[JSContext alloc] init];
NSURL *scriptURL = [NSURL URLWithString:#"https://cdn.rawgit.com/Ambisafe/client-javascript/master/dist/ambisafe.js"];
NSError *error = nil;
NSString *script = [NSString stringWithContentsOfURL:scriptURL encoding:NSUTF8StringEncoding error:&error];
[self.jsContext evaluateScript:script];
When I run the following code, I have the expected results:
NSString *script = [NSString stringWithFormat:#"Ambisafe.generateRandomValue"];
NSString *value = [[self.jsContext evaluateScript:script] toString];
Results:
function (length) {
var randomBytes;
if (!length) {
length = 256 / 16;
}
randomBytes = crypto.randomBytes(Math.ceil(length));
return randomBytes.toString('hex');
}
When I try to run the indicated function, I have an "undefined" result:
NSString *script = [NSString stringWithFormat:#"Ambisafe.generateRandomValue(30)"];
NSString *value = [[self.jsContext evaluateScript:script] toString];
I executed the following code, and I have an "undefined" result too:
NSString *script = [NSString stringWithFormat:#"crypto"];
NSString *value = [[self.jsContext evaluateScript:script] toString];
If I test the indicated javascript library on a browser, it works fine!
Please check the Fiddle link.
Any idea?

I found the origin of the problem.
The indicated library uses the "window.crypto.getRandomValues" and it doesn't work in older browsers.
https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues

Related

How can we run a node js file form objective-c

I have a macOS project using objective-c. Basically I new to creating application for macOS. I don't not objective-c or swift but I have a nodejs file that I need to run and not sure how to.
#import <Cocoa/Cocoa.h>
int main(int argc, const char *argv[]) {
- (NSString *)runCommand:(NSString *)commandToRun
{
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/nodefile.js"];
NSArray *arguments = [NSArray arrayWithObjects:
#"-c" ,
[NSString stringWithFormat:#"%#", commandToRun],
nil];
NSLog(#"run command:%#", commandToRun);
[task setArguments:arguments];
NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
NSFileHandle *file = [pipe fileHandleForReading];
[task launch];
NSData *data = [file readDataToEndOfFile];
NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return output;
}
return NSApplicationMain(argc, argv);
}

Compress image plugin for ios in phonegap

I am new to ios and building compress image plugin in ios for phonegap.I am not getting how to call the compress image method in my javascript. My code is, Plugin.h file
- (void) cordovaCompressimg:(CDVInvokedUrlCommand *)command;
Plugin.m file
- (void) cordovaCompressimg:(CDVInvokedUrlCommand *)command
{
UIImage *sourceImage ;
NSString *compimg =[self UIImageToBaseSixtyFour];
CDVPluginResult *pluginResult = [ CDVPluginResult
resultWithStatus : CDVCommandStatus_OK
NSData : compimg
];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
-(NSData *)UIImageToBaseSixtyFour
{
UIImage *sourceImage ;
NSData *imageData = UIImageJPEGRepresentation(sourceImage, 1.0);
NSString *base64 = [NSString stringWithFormat:#"%#",[UIImageJPEGRepresentation(sourceImage, 0.95) base64EncodedString]];
return base64;
}
plugin.js file
window.showimg = function(cimg, callback) {
cordova.exec(callback, function(err) {
callback('Nothing to echo.');
}, "PhonegapPlugin", "cordovaGetCurrentDate", [cimg]);
};
my calling function in index.html is,
function showCompressimg() {
window.showimg("", function(echoValue)
{
alert(echoValue);
});
}
The plugin is getting called but with empty image.The out put comes as null.The source image is not getting passed.Can anybody help me please,
Thanks in advance
You are passing the source image correctly, but you are not retrieving the image passed in your argument in objective-c code. Whenever you pass any argument via plugin Javascript, those arguments are stored in CDVInvokedUrlCommand instance command. So you can modify your code like this -
- (void) cordovaCompressimg:(CDVInvokedUrlCommand *)command
{
//Arguments are passed in an Array. Source Image is present at Index 0
UIImage *sourceImage = [command argumentAtIndex:0];
NSString *compimg =[self UIImageToBaseSixtyFour:sourceImage];
CDVPluginResult *pluginResult = [ CDVPluginResult
resultWithStatus : CDVCommandStatus_OK
NSData : compimg
];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
-(NSData *)UIImageToBaseSixtyFour:(UIImage *)img
{
//UIImage *sourceImage ;
NSData *imageData = UIImageJPEGRepresentation(img, 1.0);
NSString *base64 = [NSString stringWithFormat:#"%#",[UIImageJPEGRepresentation(img, 0.95) base64EncodedString]];
return base64;
}

Objective-C Dropbox SDK File Download - Listen for Download Complete

I am making a call to Objective C from a PhoneGap application to perform functions with Dropbox.
The problem I am having is that my callback to JavaScript is firing before a file is downloaded from Dropbox to the phone's local filesystem.
Here is my Objective C method that begins the file download from Dropbox -
- (void) restore:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSString* javaScript = nil;
NSLog(#"Dropbox restore method is executing");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents directory
NSString *localPath = [documentsDirectory stringByAppendingPathComponent:#"PocketHealth-backup.bk"];
NSString *dropBoxFile = #"/PocketHealth-backup.bk";
[[self restClient] loadFile:dropBoxFile intoPath:localPath];
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
javaScript = [pluginResult toSuccessCallbackString:command.callbackId];
[self writeJavascript:javaScript];
}
There is a method in Objective C that executes when the Dropbox file has been downloaded to the phone. I do get the NSLog that this method outputs after the Dropbox file download is complete. The problem is that I need to know when this event happens before I can return my JavaScript callback.
Here is the method that executes when the Dropbox file download is complete -
- (void) restClient:(DBRestClient*)client loadedFile:(NSString*)localPath
{
NSLog(#"File loaded into path: %#", localPath);
}
How can I wait until the Dropbox file download is complete before returning the JavaScript callback that is in the restore method?
Instead of writing the JavaScript into a local variable inside your restore method, add it as an iVar to your class, remove the call to writeJavascript: in your restore method and call writeJavascript from restClient:loadedFile:. Then it should get called when the download finished instead of when the actual download is started.
- (void) restore:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSLog(#"Dropbox restore method is executing");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents directory
NSString *localPath = [documentsDirectory stringByAppendingPathComponent:#"PocketHealth-backup.bk"];
NSString *dropBoxFile = #"/PocketHealth-backup.bk";
[[self restClient] loadFile:dropBoxFile intoPath:localPath];
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
self.javaScript = [pluginResult toSuccessCallbackString:command.callbackId];
}
- (void) restClient:(DBRestClient*)client loadedFile:(NSString*)localPath
{
NSLog(#"File loaded into path: %#", localPath);
[self writeJavascript:javaScript];
}

iOS Get past Login form.

I have the following code for my application.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//Set the values
NSString* firstValue = #"guest";
NSString* secondValue = #"guest";
// write javascript code in a string
NSString* javaScriptString = #"document.getElementById('Login1_UserName').value=%#;"
"document.getElementById('Login1_Password').value=%#;"
"document.forms['form1'].submit();";
// insert string values into javascript
javaScriptString = [NSString stringWithFormat: javaScriptString, firstValue, secondValue];
// run javascript in webview:
[webView stringByEvaluatingJavaScriptFromString: javaScriptString];
}
- (void)launchWebPageWithOptions
{
NSString *urlString = #"http://demo.leadtools.com/MedicalViewer/default.aspx";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *requestObject = [NSURLRequest requestWithURL:url];
[iOSWebView loadRequest:requestObject];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self launchWebPageWithOptions];
}
For some reason, I am unable to execute the automatic login using the javascript calls. I am no JS Expert so if you can see any error in my javaScriptString, PLEASE let me know,
First, change your user and password formatted values to be quoted:
NSString* javaScriptString = #"document.getElementById('Login1_UserName').value='%#';"
"document.getElementById('Login1_Password').value='%#';"
"document.forms['form1'].submit();";
Notice that I've changed value=%# to value='%#' in both cases. This will properly fill-in the input boxes.
Next, call the click() function on the Login button rather than calling submit() on the form:
NSString* javaScriptString = #"document.getElementById('Login1_UserName').value='%#';"
"document.getElementById('Login1_Password').value='%#';"
"document.getElementById('Login1_LoginButton').click()";
this will allow the onclick javascript specified for the Login button to be executed.
You are missing the string quotes.
Try this:
NSString* javaScriptString = #"document.getElementById('Login1_UserName').value='%#';"
"document.getElementById('Login1_Password').value='%#';"
"document.forms['form1'].submit();";

UIWebView stringByEvaluatingJavaScriptFromString

I'm stuck on getting some pretty basic JS to run in my UIWebView. In the web view's delegate, I have :
- (void)webViewDidFinishLoad:(UIWebView *)wView {
NSString *someHTML = [wView stringByEvaluatingJavaScriptFromString:#"document.getElementsByClassName('box')[0]"];
NSString *allHTML = [wView stringByEvaluatingJavaScriptFromString:#"document.body.innerHTML"];
NSLog(#"someHTML: %#", someHTML);
NSLog(#"allHTML: %#", allHTML);
}
but when the method is invoked, someHTML is nil while allHTML contains the entire body of the HTML in the webview.
I've run the JS in the Safari JS console and it works just fine (it finds a div of class 'box' so I know that its in the HTML)
Any suggestions?
More info:
FWIW, result in each of the following is also nil
NSString *result = [self.webView stringByEvaluatingJavaScriptFromString: #"document"];
NSLog (#"1. result: %#", result); //should log the document object?
result = [self.webView stringByEvaluatingJavaScriptFromString: #"document.body"];
NSLog (#"2. result: %#", result); //should log the document body
result = [self.webView stringByEvaluatingJavaScriptFromString: #"document.body.getElementsByClassName"];
NSLog (#"3. result: %#", result); //should log a function
result = [self.webView stringByEvaluatingJavaScriptFromString: #"document.body.getElementsByClassName('box')[0]"];
NSLog (#"4. result: %#", result); //should log the node
Changing
NSString *someHTML = [wView stringByEvaluatingJavaScriptFromString:#"document.getElementsByClassName('box')[0]"];
to
NSString *someHTML = [wView stringByEvaluatingJavaScriptFromString:#"document.getElementsByClassName('box')[0].innerHTML;"];
(added the .innerHTML)
makes all the difference in the world . . .

Categories