Its already too long i am struggling with this issue. After searching a lot I decided to post a question here.
What my app does
Captures photo
Uploads the photo on the wall of the page
Displays the facebook page wall in a UIWebview after upload is complete
Everything was working as expected 4 days back :) Suddenly something went wrong :(
Code
NSString *facebookPageURL =#"https://m.facebook.com/pages/<myPageName>/<myPageID>?v=wall"
UIWebView *webView = [[UIWebView alloc] initWithFrame:kAppFrame];
[webView setUserInteractionEnabled:NO];
[webView setBackgroundColor:[UIColor clearColor]];
webView.delegate = self;
[webView setHidden: YES];
NSURL *url = [NSURL URLWithString:[facebookPageURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] relativeToURL:[NSURL URLWithString:#"http://login.facebook.com"]];
NSMutableURLRequest *request = nil;
if(url)
request = [NSMutableURLRequest requestWithURL:url];
[webView loadRequest:request];
[self.view addSubview:webView];
[webView reload];
[self.view bringSubviewToFront:webView];
webView = nil;
Scenario
If I open the url facebookPageURL in Safari in iOS Simulator it works well
If I open the url in any browser on Mac it works well
In webView I see a white screen
If I change the facebookPageURL to remove ?v=wall to ?v=info I am stil able to see the page.(not blank screen atleast).
Note
1. My facebook Page is NOT unpublished and is visible.
2. I have cross checked the facebook page permissions.
I suspect there is something changed on facebook side overnight.
Please guide.
It seems the ever capricious Facebookhas removed the permission to view the wall. I came to this conclusion as when I tried the same thing in separate project I was getting both info and photos but for wall it turned grey
So Here the solution for al those suffering or might suffer form this issue.
I am getting a dictionary in response to the post
{"id":"<imge_id>","post_id":"<post_id>"}
http://www.facebook.com/photo.php?fbid=<imge_id>
and it works like a charm.
Edit:1
Just now I figured out an issue
For the pages with an age restriction, we need to authenticate which SSO doesn't supports for UIWebView inside my app.
I had to downgrade to NOT using SSO anymore. And now it works no matter what.
Just to add here you can find how to neatly downgrading to non-sso mechanism.
I think it's will help you
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([(NSMutableURLRequest *)request respondsToSelector:#selector(setValue:forHTTPHeaderField:)]) {
[(NSMutableURLRequest *)request setValue:#" Safari/537.1" forHTTPHeaderField:#"User_Agent"];
}
}
I hit my head against the wall on this one for a while. The same request and webview on an iPhone will pull up a facebook page, but results in a blank white page on an iPad. Changing user agent doesn't solve the problem.
I was able to hack around it by pulling down the HTML for the page I was looking for using stringWithContentsOfURL and then loading the HTML manually into the webview
You don't want to call [NSString stringWithContentsofURL from your main thread if you can help it, since it will hold up your thread until the results come back. Here is my solution for running it in the background and updating a UIWebView that I had already created and added to my subview called "facebookWebView":
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *rawHTML = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://www.facebook.com/link.to.your.page.on.facebook"] encoding:NSASCIIStringEncoding error:nil];
dispatch_async(dispatch_get_main_queue(), ^(void) {
[facebookWebView loadHTMLString:rawHTML baseURL:[NSURL URLWithString:#"http://www.facebook.com"]];
});
});
Hope this helps some people.
Related
I am facing an strange issue. I have a URL when I try to load that url in UIWebView it doesn't load web view remain blank but when I try to load the same url in Safari it works great and display the page. Is there any restriction for UIWebView like it can't load any specific type of widgets if webpage contain.
Thank in advance
UIWebView *webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
webView.delegate = self;
NSURL *url = [NSURL URLWithString:#"myurl"];
NSURLRequest *req = [[NSURLRequest alloc]initWithURL:url];
[self.view addSubview:webView];
[webView loadRequest:req];
Behaviour on Safari and the iOS simulator on your local machine will be the same. Both use the same proxy settings configured in System Preferences.
However - and here's the trick - each has their own distinct cookie store. To get the same behaviour you should first reset Safari and the Simulator.
This caught me out. My Safari URL worked because I had previously stored cookie values that enabled the server to fulfil my request. On the Simulator, no such cookies existed and therefore the server couldn't respond. On the surface it appeared as if the UIWebView just didn't work. However, that wasn't the case
Bottom line: reset both and try again.
I have a UIWebView which is adapted to a mobile style of a forum I have. In Safari, it looks and works great.
However, inside my UIWebView there is a major problem.
When quoting or editing a post, HTML is displayed inside of BBcode. Furthermore, posting code results in ignored line breaks. This problem will render my app completely unusable.
The webview is loaded like this:
//display the webview
NSString *fullURL = #"http://www.mysite.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSMutableURLRequest *requestObj = [NSMutableURLRequest requestWithURL:url];
[_webTest loadRequest:requestObj];
This is how it looks inside of mobile Safari (correctly)
And finally, how it looks inside of UIWebView (incorrectly)
What could possible be changing the way it renders between mobile safari vs UIWebView? I thought the point was their supposed to look the same!
This is because mobile safari and a webview have different user agent values.
Check out this SO post which is about a similar issue: Change User Agent in UIWebView (iPhone SDK)
Code from accepted solution:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)req navigationType:(UIWebViewNavigationType)navigationType {
NSMutableURLRequest *request = (NSMutableURLRequest *)req;
if ([request respondsToSelector:#selector(setValue:forHTTPHeaderField:)]) {
[request setValue:[NSString stringWithFormat:#"%# Safari/528.16", [request valueForHTTPHeaderField:#"User-Agent"]] forHTTPHeaderField:#"User_Agent"];
}
return YES;
}
I am loading request like this [resultsWebView loadRequest:searchRequest]; Then I do this
- (void) webViewDidFinishLoad:(UIWebView *)webView {
if ([resultsWebView canGoBack]) {
[goBackButton setEnabled:YES];
}
else {
[goBackButton setEnabled:NO];
}
if ([resultsWebView canGoForward]) {
[goForwardButton setEnabled:YES];
}
else {
[goForwardButton setEnabled:NO];
}
}
canGoBack is always returning NO.
It was working earlier, but it has stopped working suddenly(I have not done any code changes). I don't know how is this possible? Not getting any success to resolve this. There is a question on stackoverflow UIWebView canGoBack and canGoForward always return NO. But it is different as the question author was using loadData and he resolved the problem using loadRequest. But I am already using loadRequest. And again, it was working earlier, but it has stopped working suddenly(I have not done any code changes). Help me.
Cause of issue:
params = [NSString stringWithFormat:#"query=%#", searchTextField.text];
NSMutableURLRequest *searchRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://www.example.com/do/m/]];
[searchRequest setHTTPMethod:#"POST"];
[searchRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
If I use the simple request like below, it works fine.
NSURLRequest *searchRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://www.example.com/do/m/?%#", params]] ];
Thanks
The request may be fail even though you can see the page successfully rendered in the web view, you also need to set those go back/forward logics to – webView:didFailLoadWithError:.
Finally, I found that, if the URL is same in the consecutive POST requests for the loadRequest method then canGoBack does not work. It was working for simple GET requests because URLs were different.
To fix this, I sent the consecutive POST requests with two URLs, which are different from UIWebView perspective but actually same from the server perspective. I am setting the different URLs alternatively for consecutive POST requests, by adding a question-mark(?).
https://www.example.com/do/m/
https://www.example.com/do/m/?
In this way the URLs become different for consecutive POST requests of UIWebView and canGoBack method works.
Still I donot whether it is a bug in UIWebView or we can not use consecutive POST requests with UIWebView to get the canGoBack method works.
I have navigation controller with a tableview. When you click on one of the cells it pushes on a view with a uiwebview on it. You are taken to a YouTube page.
When you are on the table view in portrait and click on a cell you see the youtube page in portrait. Changing your orientation the video thumbnail does not refresh. So the thumbnail is smaller. This is fine. I actually prefer it smaller. All the content that would consume 2 lines will then consume 1 line. So in other words everything else adjusts for the new dimensions.
The problem comes in when you start off in landscape. Since the thumbnail doesn't resize on orientation change, changing to portrait mode, the image now goes off the screen, while the rest of the content adjusts correctly.
[webVIew refresh];
does work but it obviously loads the entire page again. So depending on the connection there will be a flicker or possibly the site will go white until its finished loading (on slower connections).
I also tried load the website in an iframe. I asked a similar question yesterday, this was for local pages i was creating. The answer to that question was to put <meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0;'> in the head. So I tried that with an iframe going and getting the page. That seemed like a dumb hack to begin with, but i was willing to go there. It wouldn't even load the page at all. I guess because the youtube page i'm loading redirects to yet other page. Upon further research it seemed like there were other issues with the iframe such as scrolling.
So my question is how can i:
A. Get just the thumbnail to resize/reload on orientation change
OR
B. Get the thumbnail to load in the dimensions it would load in portrait mode all the time, even if it was started in landscape.
You should override this method in your UIViewController class and do the resizing there:
(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
I found the answer, maybe someone could explain it or offer a better solution. There was also an addition bug that I had to work out.
I made sure the uiwebview had the delegate set to files owner.
I changed the parent view when it pushed the view onto the form from:
[self.navigationController pushViewController:controller animated:YES];
to (the important part being the 320, i'm restricting the view to portrait):
[self.navigationController pushViewController:controller animated:YES];
controller.webView.hidden = YES;
controller.webView.frame=CGRectMake(0, 0, 320,367);
3.On the webview i load the url as i always did:
NSURL *url = [NSURL URLWithString:sUrl];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
4.In the webviewdidfinishload i now have:
if (self.interfaceOrientation ==
UIInterfaceOrientationLandscapeLeft ||
self.interfaceOrientation ==
UIInterfaceOrientationLandscapeRight) {
self.webView.frame=CGRectMake(0, 0, 480,227);
}
self.webView.hidden = NO;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
All this would normally have solved my issue, but then i found out that the gdata url i'm getting from youtube service actually gets resolved to a 2nd url. Then i guess youtube changed their url format so it is forwarded to a 3rd url. This means that my didfinishload code was being called before the final url had loaded. To solve this i added:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[[NSString stringWithFormat:#"%#",request.URL] substringWithRange:NSMakeRange(0, 26)] isEqualToString:#"http://m.youtube.com/watch"]) {
NSString *sUrl=[NSString stringWithFormat:#"%#",request.URL];
sUrl = [sUrl stringByReplacingOccurrencesOfString:#"http://m.youtube.com/watch?" withString:#"http://m.youtube.com/#/watch?"];
NSURL *url = [NSURL URLWithString:sUrl];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestObj];
return NO;
}
//NSLog(#"request:%#",request.URL);
return YES;
}
Which im sure could be better but basically i tell it to ignore the 2nd url, and make my own change to go to the 3rd url.
Up until a few days ago it worked fine: opening facebook.com in iPad/UIWebView rendered as standard web. Now Facebook is force-rendered as touch - as if the URL was http://touch.facebook.com. This happens regardless of the UIWebView frame size. Here is a simple code for the main view controller to see the problem:
UIWebView *wv = [[UIWebView alloc] initWithFrame:self.view.frame];
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.facebook.com"]];
[wv loadRequest: req];
[self.view addSubview: wv];
I tried changing the user agent as suggested here - no good.
Using http://www.facebook.com?m2w should resolve this. "m2w" sounds like it is short for "mobile 2 web", and it's the link that you arrive at when you click "full site" from the mobile site.