iOS webpage doesn't load unless button is tapped twice - iphone

- (IBAction)saveButton:(id)sender
{
NSURL *yourURL = [NSURL URLWithString: webpageURLLabel.text ];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:yourURL];
if ([self checkURL] == YES) {
[webpagePreview loadRequest:request];
webpagePreview.scalesPageToFit = YES;
}
}
- (BOOL)checkURL
{
NSString *arrayOfStrings = [NSArray arrayWithObjects:#"http://", #"https://", nil];
NSString *stringToSearchWithin = webpageURLLabel.text;
BOOL found=NO;
for (NSString *s in arrayOfStrings)
{
if ([stringToSearchWithin rangeOfString:s].location != NSNotFound)
{
found = YES;
break;
} else
{
webpageURLLabel.text = [NSString stringWithFormat:#"http://%#", webpageURLLabel.text];
found = YES;
break;
}
}
return found;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
webpageTitleLabel.text = [webpagePreview stringByEvaluatingJavaScriptFromString:#"document.title"];
}
I debugged it and it looks like it is suppose to load. But for some reason, when you tap the button the first time, nothing happens.
If the user taps the button a second time, it works fine. Any suggestions?

Looks to me like the first time the button is clicked, webpageURLLabel.text may not have a valid URL, and so the request is not valid. Then when [self checkURL] is called, webpageURLLabel.text gets set to a valid URL, and so the next click works.
Maybe you should be calling -checkURL before you create the NSURLRequest?

There are also problems in checkURL. Note that it always returns YES. Inside the for loop is logic that reduces to:
if (some condition) {
found = YES;
break;
} else {
// Fix webpageURLLabel.text
found = YES;
break;
}
However, consider what happens if you have a valid entry that starts with #"https://". The first time through the loop the if condition fails and so #"http://" gets added to the front of the URL and you return. So #"https://valid.com" turns into #"http://https://valid.com". You need to move everything in the else outside the for loop and do it only if found is not true.

Related

How to get user details using twitter api v1.1 (Twitter error 215)

I have used the twitter api provided by twitter,to get the details but
not able to execute it, even tried to pass the authentication data
like consumer secret key, consumer key, token but the result is same.
I am able to login and receiving twitter authentication token but not able to get user details.
Below code is used by me (I am using MGtwitter engine) :
NSMutableURLRequest *request =[[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://api.twitter.com/1.1/users/show.json?screen_name=%#",username]]];
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil ];
NSString *returnString = [[NSString alloc]initWithData:returnData encoding:NSUTF8StringEncoding];
NSError *err = nil;
twitterLogin = [NSJSONSerialization JSONObjectWithData:[returnString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&err];
Error is shown as below:
errors = (
{
code = 215;
message = "Bad Authentication data";
} );
First, you need to Authenticate your request (Get permission).
second, see follow these steps:
1.Download FHSTwitterEngine Twitter Library.
2.Add the folder FHSTwitterEngine" to your project and #import "FHSTwitterEngine.h".
3.add SystemConfiguration.framework to your project.
Usage : 1.in the [ViewDidLoad] add the following code.
UIButton *logIn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
logIn.frame = CGRectMake(100, 100, 100, 100);
[logIn setTitle:#"Login" forState:UIControlStateNormal];
[logIn addTarget:self action:#selector(showLoginWindow:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:logIn];
[[FHSTwitterEngine sharedEngine]permanentlySetConsumerKey:#"<consumer_key>" andSecret:#"<consumer_secret>"];
[[FHSTwitterEngine sharedEngine]setDelegate:self];
and don't forget to import the delegate FHSTwitterEngineAccessTokenDelegate.
you need to get the permission for your request, with the following method which will present Login window:
- (void)showLoginWindow:(id)sender {
[[FHSTwitterEngine sharedEngine]showOAuthLoginControllerFromViewController:self withCompletion:^(BOOL success) {
NSLog(success?#"L0L success":#"O noes!!! Loggen faylur!!!");
}];
}
when the Login window is presented, enter your Twitter Username and Password to authenticate your request.
add the following methods to your code:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[FHSTwitterEngine sharedEngine]loadAccessToken];
NSString *username = [[FHSTwitterEngine sharedEngine]loggedInUsername];// self.engine.loggedInUsername;
if (username.length > 0) {
lbl.text = [NSString stringWithFormat:#"Logged in as %#",username];
[self listResults];
} else {
lbl.text = #"You are not logged in.";
}
}
- (void)storeAccessToken:(NSString *)accessToken {
[[NSUserDefaults standardUserDefaults]setObject:accessToken forKey:#"SavedAccessHTTPBody"];
}
- (NSString *)loadAccessToken {
return [[NSUserDefaults standardUserDefaults]objectForKey:#"SavedAccessHTTPBody"];
}
4.Now you are ready to get your request, with the following method(in this method I created a Twitter search for some Hashtag, to get the screen_name for example):
- (void)listResults {
dispatch_async(GCDBackgroundThread, ^{
#autoreleasepool {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// the following line contains a FHSTwitterEngine method wich do the search.
dict = [[FHSTwitterEngine sharedEngine]searchTweetsWithQuery:#"#iOS" count:100 resultType:FHSTwitterEngineResultTypeRecent unil:nil sinceID:nil maxID:nil];
// NSLog(#"%#",dict);
NSArray *results = [dict objectForKey:#"statuses"];
// NSLog(#"array text = %#",results);
for (NSDictionary *item in results) {
NSLog(#"text == %#",[item objectForKey:#"text"]);
NSLog(#"name == %#",[[item objectForKey:#"user"]objectForKey:#"name"]);
NSLog(#"screen name == %#",[[item objectForKey:#"user"]objectForKey:#"screen_name"]);
NSLog(#"pic == %#",[[item objectForKey:#"user"]objectForKey:#"profile_image_url_https"]);
}
dispatch_sync(GCDMainThread, ^{
#autoreleasepool {
UIAlertView *av = [[UIAlertView alloc]initWithTitle:#"Complete!" message:#"Your list of followers has been fetched" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
});
}
});
}
That's all.
I just got the screen_name from a search Query, you can get a timeline for a user using the following methods:
// statuses/user_timeline
- (id)getTimelineForUser:(NSString *)user isID:(BOOL)isID count:(int)count;
- (id)getTimelineForUser:(NSString *)user isID:(BOOL)isID count:(int)count sinceID:(NSString *)sinceID maxID:(NSString *)maxID;
instead of the search method above.
Note: see the FHSTwitterEngine.h to know what method you need to use.
Note: to get the <consumer_key> and the <consumer_secret> you need to to visit this link
to register your app in Twitter.
Got the solution after MKAlatrash revert, to get the user profile follow certain steps in the code as under :
[[FHSTwitterEngine sharedEngine]getProfileImageForUsername:username andSize:FHSTwitterEngineImageSizeNormal];
jump to definition of this function and replace the if ... else if part
if ([userShowReturn isKindOfClass:[NSError class]]) {
return [NSError errorWithDomain:[(NSError *)userShowReturn domain] code:[(NSError *)userShowReturn code] userInfo:[NSDictionary dictionaryWithObject:request forKey:#"request"]];
NSLog(#"user show return %#",userShowReturn);
} else if ([userShowReturn isKindOfClass:[NSDictionary class]]) {
return userShowReturn;
NSString *url = [userShowReturn objectForKey:#"profile_image_url"]; // normal
if (size == 0) { // mini
url = [url stringByReplacingOccurrencesOfString:#"_normal" withString:#"_mini"];
} else if (size == 2) { // bigger
url = [url stringByReplacingOccurrencesOfString:#"_normal" withString:#"_bigger"];
} else if (size == 3) { // original
url = [url stringByReplacingOccurrencesOfString:#"_normal" withString:#""];
}
id ret = [self sendRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
if ([ret isKindOfClass:[NSData class]]) {
return [UIImage imageWithData:(NSData *)ret];
}
return ret;
}
That really was helpful thanks

iOS GameCenter Matchmaker not working

I’m trying to make a custom matchmakingview using a matchmaker. The code below is used to find a match.
When i run this on two different devices with different Game Center accounts, both will get a match but none will connect to the match. They will just get stuck in the while loop in infinity and never get out. Have i missed something, do you need to call something to actually connect to the match?
- (void) findMatch{
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playersToInvite = nil;
NSLog(#"Start searching!");
[matchmaker findMatchForRequest:request
withCompletionHandler:^(GKMatch *match, NSError *error)
{
if (error) {
// Print the error
NSLog(#"%#", error.localizedDescription);
}
else if (match != nil)
{
curMatch = match;
curMatch.delegate = self;
NSLog(#"Expected: %i", match.expectedPlayerCount);
while (match.expectedPlayerCount != 0){
NSLog(#"PLayers: %i", curMatch.playerIDs.count);
}
NSLog(#"Start match!");
}
}];
You should not be using a while loop to wait for expectedPlayerCount to reach 0, instead implement the GKMatchDelegate method:
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
if (!self.matchStarted && match.expectedPlayerCount == 0) {
self.matchStarted = YES;
//Now you should start your match.
}
}

iTunes isRunning with NSTask

So I am trying to make an if based on if iTunes is running or not. I need this because my application gets the track name. This track name has already been accomplished and works but I do not want iTunes always running...
So I decided to try a NSTask with setLaunchPath instance to check if iTunes.app isRunning. The code below is self explanatory but for some reason it keeps hitting my else if when iTunes is open. I call this method in my awakeFromnib by an nstimer every 5 seconds.
-(IBAction)ifRunning:(id)pID; {
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/Applications/iTunes.app/Contents/MacOS/iTunes"];
if ([task isRunning]==TRUE) {
NSLog(#"iTunes is Running, hit if");
NSString *track = ([self getCurrentTrack]);
//getCurrentTrack another one of my methods
}
else if ([task isRunning] == FALSE) {
NSLog(#"iTunes is not running, hit else if");\
[trackName setTitle:(#"iTunes is Not Playing")];
}
else {
NSLog(#"Hit else");
}
}
I figured it out using the code below. Hope this post is useful!
-(IBAction)ifRunning:(id)pID; {
NSLog(#"Process check ");
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSArray *runningAppDictionaries = [ws launchedApplications];
NSDictionary *aDictionary;
for (aDictionary in runningAppDictionaries)
{
// NSLog(#"Open App: %#", [aDictionary valueForKey:#"NSApplicationName"]);
if ([[aDictionary valueForKey:#"NSApplicationName"] isEqualToString:#"iTunes"])
{
NSLog(#"iTunes is Is Running");
[self getCurrentTrack:nil];
break;
}
else {
NSLog(#"iTunes is not running.");
}
}
}

Not firing self.viewcontroller.webview.delegate = self+PhoneGap+secondtime

I have to reload the mainviewcontroller webview second time and reload the webview.
APPDELGATE:
- (void) webViewDidFinishLoad:(UIWebView*) theWebView
{
// only valid if FooBar.plist specifies a protocol to handle
if (self.invokeString)
{
// this is passed before the deviceready event is fired, so you can access it in js when you receive deviceready
NSString* jsString = [NSString stringWithFormat:#"var invokeString = \"%#\";", self.invokeString];
[theWebView stringByEvaluatingJavaScriptFromString:jsString];
}else {
if([loginComplete isEqualToString:#"1"] ){
NSString *page = #"intro.html";
NSString* jsString = [NSString stringWithFormat:#"loadParams('%#','%#','%#');", at,userfbid,page];
[theWebView stringByEvaluatingJavaScriptFromString:jsString];
}
else {
NSString *page = #"friends.html";
NSString* jsString = [NSString stringWithFormat:#"loadParams('%#','%#','%#');", at,userfbid,page];
[theWebView stringByEvaluatingJavaScriptFromString:jsString];
}
// Black base color for background matches the native apps
theWebView.backgroundColor = [UIColor grayColor];
return [self.viewController webViewDidFinishLoad:theWebView];
}
-(void)insert{
self.viewcontroller.webview.delegate=self;
}
Webdelegate is not firing in insert.
Thanks
Try this:
return [self webViewDidFinishLoad:theWebView];
instead of:
return [self.viewController webViewDidFinishLoad:theWebView];
Because your AppDelegate is the delegate for webView's webViewDidFinishLoaded, not webView itself.

If-Then statement confusion, NSURL result not working quite right

What I would like to do is take the [self getYear] method which is predefined and returns an NSString in the form of a year (i.e. 1995), and then take that number and match it to which year it actually is, and set that to a URL variable, theClassyear. When this project is run, i have this as part of a setup method in -viewWillAppear and when I pull up the view (this is in a tab bar controller fyi) then I get either an NSURL error 101 or error -999. The [self getYear] method takes it's string from a NSUserDefaults string that is set by a UIPicker in a different view pushed by the controller. Like I said, when I first open the view and this method runs I get the correct result from the first NSLog, but then it runs through my if statements and ends up using the else statement which sets my NSURL that is supposed to be returned to null (according to my NSLog). Later on in the code I have another NSLog that prints the [self getYear] result again and that gives me the right number also. somehow my if-then logic is not running through correctly and I would love advice on what I may be doing wrong. Thanks in advance!!! :)
-(NSURL *)theClassYear{
NSURL *theClassYear = [[NSURL alloc] init];
NSLog(#"the user default loaded for the year is: %#",[self getYear]);
if ([self getYear] == #"1995") {
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=35443264449"];
}
else if ([self getYear] == #"1996"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=50371222704"];
}
else if ([self getYear] == #"1997"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=101880069858690"];
}
else if ([self getYear] == #"1998"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=98761155252"];
}
else if ([self getYear] == #"1999"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=34955119113"];
}
else if ([self getYear] == #"2000"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=41438241821"];
}
else if ([self getYear] == #"2001"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=44108047608"];
}
else if ([self getYear] == #"2002"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=98700780436"];
}
else if ([self getYear] == #"2003"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=36811255052"];
}
else if ([self getYear] == #"2004"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=40331531709"];
}
else if ([self getYear] == #"2005"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=97724430117"];
}
else if ([self getYear] == #"2006"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=50868469971"];
}
else if ([self getYear] == #"2007"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=38506528654"];
}
else if ([self getYear] == #"2008"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=55466866222"];
}
else if ([self getYear] == #"2009"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=105187085612"];
}
else if ([self getYear] == #"2010"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=39303927757"];
}
else if ([self getYear] == #"2011"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=281837582821"];
}
else if ([self getYear] == #"2012"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=79162636609"];
}
else if ([self getYear] == #"2013"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/home.php?sk=group_161338720557447"];
}
else if ([self getYear] == #"2014"){
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/home.php?sk=group_125352334187406"];
}
else {
NSLog(#"no matches");
}
NSLog(#"the url for the year you chose is: %#",theClassYear);
return theClassYear;
[theClassYear release];
}
More on my comment above
Put this data in a plist, grab the plist (which will be an NSDictionary called dict in this case) and then return [NSURL URLWithString:[dict objectForKey:[self getYear]]];
When you use == on objects such as NSString in Objective-C, you are not comparing the values of the objects, but the memory address of the object.* If you have two strings, and you want to see whether their contents are the same, you must, as Mahesh mentioned, use isEqualToString:, which does the correct comparison.
There are a couple of other things that can improved in your code. First, you are leaking an NSURL. You first create one with
NSURL *theClassYear = [[NSURL alloc] init];
and then you ignore it and create another one in one of the branches of your if:
theClassYear = [NSURL URLWithString:#"http://www.facebook.com/group.php?gid=35443264449"];
// This creates a new NSURL instance and leaks the old one.
To fix this, simply remove the initial assignment and make it a declaration:
NSURL * theClassYear; // You will assign to this name later, in a branch
Next, as Mahesh also pointed out, once you say return in a method, nothing past that line gets executed, so your [theClassYear release] does not occur. In this case, it's actually unnecessary, too.** The object that you get back from URLWithString: is autoreleased, which in this case is exactly what you want.
Finally, please do take Rexeisen's advice about putting all those strings into a dictionary. It will make your code much easier to read and more maintainable.
*Unlike interpreted languages such as Python, Perl, or PHP, or compiled languages with operator overloading such as C++.
**In fact, if it were running it would cause a crash due to overreleasing.