I'm trying to get access token,I'm following this link to get that,but some condition fails,I think am not properly append the javascript with HTML content.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if(_data)
{
NSString* content = [[NSString alloc] initWithData:_data
encoding:NSUTF8StringEncoding];
[_data release];
_data = nil;
NSString *jsString = #"<script type='text/javascript'>\
window.external =\
{\
'Notify': function(s) { document.location = 'acs://settoken?token=' + s; },\
'notify': function(s) { document.location = 'acs://settoken?token=' + s; }\
}\
</script>";
content = [jsString stringByAppendingString:content];
[webView loadHTMLString:content baseURL:_url];
}
}
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
if(_url)
{
if([_url isEqual:[request URL]])
{
return YES;
}
[_url release];
}
//Here am getting http://LoginSuccess.aspx
_url = [[request URL] retain];
NSString* scheme = [_url scheme];//Here am getting http
//So here condition fails
if([scheme isEqualToString:#"acs"])
{
// parse the JSON URL parameter into a dictionary
_url = [NSURL URLWithString:#"https://converse.accesscontrol.windows"];
NSDictionary* pairs = [self parsePairs:[_url absoluteString]];
if(pairs)
{
WACloudAccessToken* accessToken;
accessToken = [[WACloudAccessToken alloc] initWithDictionary:pairs];
//[WACloudAccessControlClient settoken:accessToken];
[self dismissModalViewControllerAnimated:YES];
}
return NO;
}
[NSURLConnection connectionWithRequest:request delegate:self];
return NO;
}
Any ideas? Thanks in advance.
I´m not sure if i unterstand exactly what you´re trying to do, but I assume
[UIWebView stringByEvaluatingJavaScriptFromString:#"yourJavaString"];
could help. I use it to perform an JavaScript based Loginmechanism in one of my projects.
See the Apple doc here .
You have to use stringByEvaluatingJavaScriptFromString AFTER WebView has loaded.
Related
I'm new to iPhone development,I'm trying to get access token,I have to complete that task in time.I got this link http://www.stevesaxon.me/posts/2011/window-external-notify-in-ios-uiwebview/ to do that,but I couldn't able to understand clearly.Can anyone help me?
How to call the given javascript properly in below code?
<script type='text/javascript'>\
window.external =\
{\
'Notify': function(s) { document.location = 'acs://settoken?token=' + s; },\
'notify': function(s) { document.location = 'acs://settoken?token=' + s; }\
}\
</script>
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if(_data)
{
NSString* content = [[NSString alloc] initWithData:_data
encoding:NSUTF8StringEncoding];
[_data release];
_data = nil;
NSString* jsString = #"<script type='text/javascript'>\
window.external =\
{\
'Notify': function(s) { document.location = 'acs://settoken?token=' + s; },\
'notify': function(s) { document.location = 'acs://settoken?token=' + s; }\
}\
</script>";
NSString *result = [webView stringByEvaluatingJavaScriptFromString: jsString];
content = [content stringByAppendingString:result];
[webView loadHTMLString:content baseURL:_url];
}
}
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
if(_url)
{
if([_url isEqual:[request URL]])
{
return YES;
}
[_url release];
}
//Here am getting http://LoginSuccess.aspx
_url = [[request URL] retain];
NSString* scheme = [_url scheme];//Here am getting http
//So here condition fails
if([scheme isEqualToString:#"acs"])
{
// parse the JSON URL parameter into a dictionary
_url = [NSURL URLWithString:#"https://converse.accesscontrol.windows"];
NSDictionary* pairs = [self parsePairs:[_url absoluteString]];
if(pairs)
{
WACloudAccessToken* accessToken;
accessToken = [[WACloudAccessToken alloc] initWithDictionary:pairs];
//[WACloudAccessControlClient settoken:accessToken];
[self dismissModalViewControllerAnimated:YES];
}
return NO;
}
[NSURLConnection connectionWithRequest:request delegate:self];
return NO;
}
Any ideas? Thanks in advance.
Try this :-
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if(_data)
{
NSString* content = [[NSString alloc] initWithData:_data
encoding:NSUTF8StringEncoding];
[_data release];
_data = nil;
NSString* Html = #" <script type='text/javascript'>\
window.external =\
{\
'Notify': function(s) { document.location = 'acs://settoken?token=' + s; },\
'notify': function(s) { document.location = 'acs://settoken?token=' + s; }\
}\
</script>";
//Here to call that javascript
NSString *result = [_webView stringByEvaluatingJavaScriptFromString:Html];
content = [ScriptNotify stringByAppendingString:result];
[webView loadHTMLString:content baseURL:_url];
}
}
I have seen almost all the posts about NSURL on this site, and I am still stuck. I am using Xcode 4.5.
I am trying to download images and display them in a UIScrollView.
I want to download asynchronously download images using URLs, that get stored in an array populated using JSON. I get the URLs from a JSON grab off of my database. That works quite well and I can see the URL's being placed into the urlArray, but making the URLConnection to get the image, seems to fail.
I can't get any of the images to download, or at least they don't show up in my imageArray.
Here is my code and thank you for any help!! Let me know what else is needed
- (void)viewDidLoad
{
[super viewDidLoad];
//show network activity to user.... very useful
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//call getJSON. getJSON does not parse, but it connects and gets the data.
[self getJSON];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)getJSON
{
NSURL *url = [NSURL URLWithString:#"http://"My server goes here/json.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//just initialize the connection, do not
[[NSURLConnection alloc] initWithRequest:request delegate:self]; //"Ecression result unused" warning here
}
- (void)getNextImage
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
for (int y = 0; y < urlArray.count; y++)
{
NSString *urlString = [urlArray objectAtIndex:y];
NSLog(#"Array String is: %# ", urlString);
NSURL *arrayURL = [NSURL URLWithString:urlString];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:arrayURL];
NSData *imgData = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self]; //"Incompatible pointer types initializing ..." warning here
imageData = [UIImage imageWithData:imgData];
[imageArray addObject:imageData];
}
NSLog(#"LEAVING getNextImage");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
theJsonData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[theJsonData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
urlArray = [[NSMutableArray alloc] init];
//This is where all the JSON Parsing is being done.
//Turn off the data indicator, because the download is complete.
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
jsonArray = [NSJSONSerialization JSONObjectWithData:theJsonData options:nil error:nil]; //"Incompatible pointer types initializing ..." warning here
//get the URL strings out of the jsonArray
for (int x = 0; x < jsonArray.count; x++)
{
NSString *urlString = [[jsonArray objectAtIndex:x] objectForKey:#"image_URL"];
NSLog(#"String is %# ", urlString);
[urlArray addObject:urlString];
}
[self getNextImage];
//display the images..... Not sure why this is in connectionDidFinishLoading.
for (int x = 0; x < imageArray.count; x++)
{
CGRect frame;
frame.origin.x = self.mainScroll.frame.size.width * x;
frame.origin.y = 0;
frame.size = self.mainScroll.frame.size;
UIImageView *nextIV = [[UIImageView alloc] initWithFrame:frame];
[nextIV setImage:imageData];
[self.mainScroll addSubview:nextIV];
//NSLog(#"Pass %d", x);
}
self.mainScroll.contentSize = CGSizeMake(self.mainScroll.frame.size.width * imageArray.count,1.0);
NSLog(#"!!!!!!leaving connection did finnish loading!!!!!");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//show error message to user if there is a connection error.
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"The Download could not complete - please make sure you're connected to the internet." delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[errorView show];
//turn off the network activity indicatior
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
you never download imageData. you assign it the request object . thats why you get the warning too. a NSURLConnection object is not a NSData object: NSData *imgData = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self]; //"Incompatible pointer types initializing ..." warning here
I would today rewrite it using the startAsyncConnection method. sec
-- there you go, untested and written in text edit but it should get you started (I reused most of your code but cut it down a lot too)
#import "RootViewController.h"
#interface RootViewController ()
#property(assign) IBOutlet UIScrollView *mainScroll;
#end
#implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self getJSONAndImageData];
}
- (void)getJSONAndImageData
{
NSURL *url = [NSURL URLWithString:#"http://My server goes here/json.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse*r, NSData*d, NSError*e) {
[self parseJSONAndGetImages:d];
}];
}
- (void)parseJSONAndGetImages:(NSData*)data
{
NSMutableArray *urlArray = [[NSMutableArray alloc] init];
//This is where all the JSON Parsing is being done.
//Turn off the data indicator, because the download is complete.
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSArray *jsonArray = (NSArray*)[NSJSONSerialization JSONObjectWithData:data options:nil error:nil]; //"Incompatible pointer types initializing ..." warning here => likely not an array then
assert([jsonArray isKindOfClass:[NSArray class]]);
//could be made in one liner with KVC
//get the URL strings out of the jsonArray
for (int x = 0; x < jsonArray.count; x++)
{
NSString *urlString = [[jsonArray objectAtIndex:x] objectForKey:#"image_URL"];
NSLog(#"String is %# ", urlString);
[urlArray addObject:urlString];
}
[self loadImageArray:urlArray handler:^(NSArray* imageArray) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
for (int x = 0; x < imageArray.count; x++)
{
CGRect frame;
frame.origin.x = self.mainScroll.frame.size.width * x;
frame.origin.y = 0;
frame.size = self.mainScroll.frame.size;
UIImageView *nextIV = [[UIImageView alloc] initWithFrame:frame];
[nextIV setImage:imageArray[x]];
[self.mainScroll addSubview:nextIV];
//NSLog(#"Pass %d", x);
}
self.mainScroll.contentSize = CGSizeMake(self.mainScroll.frame.size.width * imageArray.count,1.0);
}];
}
//for SIMPLICITY I do synchronous networking here!
- (void)loadImageArray:(NSArray *)urlArray handler:(void(^)())handler {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSMutableArray *imageArray = [NSMutableArray array];
for (int y = 0; y < urlArray.count; y++)
{
NSString *urlString = [urlArray objectAtIndex:y];
NSLog(#"Array String is: %# ", urlString);
NSURL *arrayURL = [NSURL URLWithString:urlString];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:arrayURL];
NSData *imgData = [NSURLConnection sendSynchronousRequest:imageRequest returningResponse:nil error:nil];
UIImage *image = [UIImage imageWithData:imgData];
[imageArray addObject:image];
}
dispatch_async(dispatch_get_main_queue(),^ {
handler(imageArray);
});
});
}
#end
I am trying to create an iPhone app as in the fig below:
In this i am dynamically adding some imageviews dynamically into a uiscroll view. Each imageview contains a UIButton and UIProgressView. When click on each it should different urls and the loading of each url should appear on the corresponding UIProgressView. I am using asynchronous method and it should load multiple progress views at the same time.
Here is the code i have used,
- (void)startDownload:(id)sender {
UIButton *btn = (UIButton *)sender;
int btnTag = btn.tag;
selectedTag = btn.tag;
for (int x=0; x < [urlArray count]; x++) {
if (btnTag == x) {
NSURL *url = [NSURL URLWithString:[urlArray objectAtIndex:x]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *theConnection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(#"Expected length: %lld ",response.expectedContentLength);
}];
if (theConnection) {
receivedData = [NSMutableData data];
}else {
NSLog(#"Connection failed");
}
}
}
}
- (void)makeMyProgressMove{
UIImageView *image = (UIImageView *)[mainView viewWithTag:selectedTag];
UIProgressView *currentProgress = (UIProgressView *)[image viewWithTag:selectedTag];
NSLog(#"Prog tag: %d",currentProgress.tag);
if(currentProgress)
{
float actualProgress = (_receivedDataBytes / (float)_totalFileSize);
currentProgress.progress = actualProgress;
} else {
NSLog( #"couldn't get the progress view for the image with tag: %d", selectedTag );
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
_totalFileSize = response.expectedContentLength;
receivedData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
_receivedDataBytes += [data length];
NSLog(#"Receiving data: %2f", _receivedDataBytes / (float)_totalFileSize);
if ((_receivedDataBytes / (float)_totalFileSize) < 1) {
[self performSelectorOnMainThread: #selector(makeMyProgressMove) withObject: NULL waitUntilDone:NO];
}
else if ((_receivedDataBytes / (float)_totalFileSize) == 1){
[self performSelectorOnMainThread: #selector(makeMyProgressMove) withObject: NULL waitUntilDone:NO];
_receivedDataBytes = 0;
_totalFileSize = 0;
}
[receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Succeeded! Received %d bytes of data",[receivedData length]);
}
But its not working.
Any idea?
allocate each UIWebView with different url and and addSubView UIActivityIndicatorView to every UIWebView.Give tag for each UIActivityIndicator ..
-(void)action {
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlAddress];
//URL Request Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
UIWebView *webView = [[UIWebView alloc]initWithFrame:frame];//give y value incremented frame.
UIActivityIndicatorView *av = [[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
av.frame=CGRectMake(145, 160, 25, 25);
av.center = webView.center;
av.tag = INDICATOR_TAG;
[webView addSubview:av];
webView.delegate = self;
[av startAnimating];
//Load the request in the UIWebView.
[webView loadRequest:requestObj];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
UIActivityIndicatorView *indicator = [webView viewWithTag:INDICATOR_TAG];
indicator.hidden = YES;
}
call this action{} method for showing multiple times.
EDIT
UIWebView doesn't give you any progress information in the normal mode. What you need to do is first fetch your data asynchronously using an NSURLConnection. When the NSURLConnection delegate method connection:didReceiveResponse, you're going to take the number you get from expectedContentLength and use that as your max value. Then, inside the delegate method connection:didReceiveData, you're going to use the length property of the NSData instance to tell you how far along you are, so your progress fraction will be length / maxLength , normalized to between 0 and 1.
Finally, you're going to init the webview with data instead of a URL (in your connection:didFinishLoading delegate method).
Reference :
How to use UIProgressView while loading of a UIWebView?
I have changed tel property to do some string manipulation instead of calling that number.
its working in simulator but when i do it device, its still trying to call.
i have tried with webview, textview, button still same problem :(
Any idea?
Let me rephrase
By default, when clicked on any link with tel:xxxx iPhone calls number xxxx
But i don't want calling, instead i want to grab xxxx and append that value to my String.
How to do that.
Thanks
- (void)viewDidLoad {
[super viewDidLoad];
self.htmlString = [self createHTML];
[webView setBackgroundColor:[UIColor clearColor]];
[webView setOpaque:NO];
[webView loadHTMLString:self.htmlString baseURL:nil];
}
- (NSMutableString *) createHTML {
NSMutableString *tempString =[NSMutableString stringWithFormat:#"<div>"];
[tempString appendString:#"John Smith"];
[tempString appendFormat:#"<br> <a href='tel:201207415'>201207415</a>"];
[tempString appendString:#"</div>"];
return tempString;
}
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
//CAPTURE USER LINK-CLICK.
NSURL *url = [request URL];
NSString *mytext = [url absoluteString];
NSLog(#"%#",mytext);
myLabel.text = mytext;
return YES;
}
If you do not want to call:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
return NO;
}
Simulator cannot call anyway.
I have an app that uses a segmentedControl. First item is an "All" item, where the rest is created from an array based on result from webservice. When "All" is selected I want to request all the request.
How can I go about this,
NSArray *urls = [NSArray arrayWithObjects:#"http://service/group/1/",
#"http://service/group/2/", nil];
I want to collect all result from the calls into a collection and display it in a UITableView when the "All" item is selected and probably in viewDidLoad.
For the other segments only one of the request is issued and callback with an array that then is used in:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
I have tried to look at this example for making the request from the array MultipleDownloads
Thanks,
The method in my viewController to initiate the multiple download:
- (void)requestChildrenInBackground {
queue = [[NSOperationQueue alloc] init];
//Todo remove hard coded and get from previous request respons
NSArray *urls = [NSArray arrayWithObjects: #"http://service/1/children",
#"http://service/2/children",
#"http://service/3/children", nil];
NSLog(#"%#", urls);
for (NSString * url in urls)
{
GetSchedule *operation =
[GetSchedule urlDownloaderWithUrlString:url];
[queue addOperation:operation];
}
}
This is how the multiple request gets handled:
#import "GetSchedule.h"
#import "JSON.h"
#import "Authentication.h"
#import "AttendanceReportViewController.h"
#interface GetSchedule ()
- (void)finish;
#end
#implementation GetSchedule
#synthesize appDelegate;
#synthesize username;
#synthesize password;
#synthesize authenticationString;
#synthesize encodedLoginData;
#synthesize schedulesArray;
#synthesize url = _url;
#synthesize statusCode = _statusCode;
#synthesize data = _data;
#synthesize error = _error;
#synthesize isExecuting = _isExecuting;
#synthesize isFinished = _isFinished;
+ (id)urlDownloaderWithUrlString:(NSString *)urlString {
NSURL * url = [NSURL URLWithString:urlString];
GetSchedule *operation = [[self alloc] initWithUrl:url];
return [operation autorelease];
}
- (id)initWithUrl:(NSURL *)url {
self = [super init];
if (self == nil)
return nil;
_url = [url copy];
_isExecuting = NO;
_isFinished = NO;
return self;
}
- (void)dealloc
{
[username release];
[password release];
[encodedLoginData release];
[_url release];
[_connection release];
[_data release];
[_error release];
[super dealloc];
}
- (BOOL)isConcurrent
{
return YES;
}
- (void)start
{
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:#selector(start) withObject:nil waitUntilDone:NO];
return;
}
self.username = appDelegate.username;
self.password = appDelegate.password;
Authentication *auth = [[Authentication alloc] init];
authenticationString = (NSMutableString*)[#"" stringByAppendingFormat:#"%#:%#", username, password];
self.encodedLoginData = [auth encodedAuthentication:authenticationString];
[auth release];
NSLog(#"operation for <%#> started.", _url);
[self willChangeValueForKey:#"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:#"isExecuting"];
// Setup up the request with the url
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:_url];
[request setHTTPMethod:#"GET"];
[request setValue:[NSString stringWithFormat:#"Basic %#", encodedLoginData] forHTTPHeaderField:#"Authorization"];
_connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
if (_connection == nil)
[self finish];
else {
_data = [[NSMutableData alloc] init];
}
}
- (void)finish
{
NSLog(#"operation for <%#> finished. "
#"status code: %d, error: %#, data size: %u",
_url, _statusCode, _error, [_data length]);
[_connection release];
_connection = nil;
[self willChangeValueForKey:#"isExecuting"];
[self willChangeValueForKey:#"isFinished"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:#"isExecuting"];
[self didChangeValueForKey:#"isFinished"];
}
#pragma mark -
#pragma mark NSURLConnection delegate
- (void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse *)response
{
//[_data release];
//_data = [[NSMutableData alloc] init];
[_data setLength:0];
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;
_statusCode = [httpResponse statusCode];
}
- (void)connection:(NSURLConnection *)connection
didReceiveData:(NSData *)data
{
[_data appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// Parse the responseData of json objects retrieved from the service
SBJSON *parser = [[SBJSON alloc] init];
NSString *jsonString = [[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding];
NSDictionary *jsonData = [parser objectWithString:jsonString error:nil];
NSMutableArray *array = [jsonData objectForKey:#"Children"];
schedulesArray = [NSMutableArray array];
[schedulesArray addObject:array];
// Callback to AttendanceReportViewController that the responseData finished loading
[attendanceReportViewController loadSchedule];
[self finish];
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
_error = [error copy];
[self finish];
}
#end
When all data is received I want to call back to my ViewController and get an array with all data from all request made.
Create a downloader
Create a downloader class using NSURLConnection.
Keep a member variable called downloaderObjectId.
Write a delegate method for this object. This method will pass the downloaded data and downloaderObjectId back to the delegate.
In the delegate.
Create multiple downloader objects(As per your ncessity) with unique value for the downloaderObjectId.
Store these objects in a NSMutableDictionary
Key for each object will be downloaderObjectId. so that when the delegate method is called after download you take the exact object back from the NSMutableDictionary using this key.
Main point.
Each time delegate is called. You should remove the object from dictionary(The object who is done with the download and called his delgate. You can identify this object by the key downloaderObjectId he holds. )
Then check the count of dictionary. If it is zero you can make sure that your downloads are completed. So you can call your viewcontroller.