There is a Semantic Issue with my code. I have a UIWebView and I added an error message so if there's no internet connection, an error pops up.
This is the coding for my UIWebView in my .m file
- (void)viewDidLoad {
[super viewDidLoad];
NSString *fullURL = #"http://example.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[website setDelegate:self];
[website loadRequest:requestObj]; }
The error is on this code
[website setDelegate:self];
It says it's a Semantic Issue and the error is Sending FirstViewController *const_strong to parameter of incompatible type id
Here is the code for the error message if there is no internet connection
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"error" message:#"error connecting to the internet" delegate:self
cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show]; }
You need to specify that FirstViewController implements protocol. Something like:
#interface FirstViewController () <UIWebViewDelegate>
#end
The compiler is currently warning you that you're setting a delegate which isn't specifying that it implements the required protocol so no compile check is being performed.
Your view controller should specify that it conforms to UIWebViewDelegate by adding "<UIWebViewDelegate>" to the end of the #interface line, either in the main #interface declaration in the .h:
#interface MyViewController : UIViewController <UIWebViewDelegate>
Or to the private class extension (if you have one) in the .m file:
#interface MyViewController () <UIWebViewDelegate>
See Conforming to Protocols in the Programming with Objective-C guide.
Related
I'm trying to get my Cognito login to work.
The problem is that it's not working and I'm not getting error messages from AWS, or XCode. I've implemented it according to the tutorial and the AWS sample code (maybe wrongly?). I've tried to understand how the code works by adding a couple of NSlog's within the AWS cognito functions so that I know whether they get excecuted, but they do not show up in my console either. Why are these function not being run without even sending an error? Is there something obvious that I'm forgetting?
Here's the essential parts of my code
// loginviewcontroller.h
#import AWSCognitoIdentityProvider;
#interface LoginViewController : UIViewController <AWSCognitoIdentityPasswordAuthentication>
#property (nonatomic, strong) NSString * usernameText;
#end
loginviewcontroller.m file:
// loginviewcontroller.m
#property (nonatomic, strong) AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails*> *passwordAuthenticationCompletion;
- (IBAction)signInPressed:(UIButton *)sender {
self.passwordAuthenticationCompletion.result = [[AWSCognitoIdentityPasswordAuthenticationDetails alloc] initWithUsername:self.userName.text password:self.password.text];
NSLog(#"button pressed");};
-(void) getPasswordAuthenticationDetails: (AWSCognitoIdentityPasswordAuthenticationInput *) authenticationInput passwordAuthenticationCompletionSource: (AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails *> *) passwordAuthenticationCompletionSource {
//keep a handle to the completion, you'll need it continue once you get the inputs from the end user
self.passwordAuthenticationCompletion = passwordAuthenticationCompletionSource;}
-(void) didCompletePasswordAuthenticationStepWithError:(NSError*) error {
NSLog(#"didCompletePasswordAuthenticationStepWithError");
dispatch_async(dispatch_get_main_queue(), ^{
//present error to end user
if(error){
NSLog(#"Error");
[[[UIAlertView alloc] initWithTitle:error.userInfo[#"__type"]
message:error.userInfo[#"message"]
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil] show];
}else{
NSLog(#"Success");
//dismiss view controller
[self dismissViewControllerAnimated:YES completion:nil];
}
});
appdelegate.h
//appdelegate.h
#import AWSCognitoIdentityProvider;
#interface AppDelegate : UIResponder <UIApplicationDelegate, AWSCognitoIdentityInteractiveAuthenticationDelegate>
#property(nonatomic,strong) LoginViewController* LoginViewController;
appdelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//setup AWS service config
AWSServiceConfiguration *serviceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:nil];
//create a pool
AWSCognitoIdentityUserPoolConfiguration *configuration = [[AWSCognitoIdentityUserPoolConfiguration alloc] initWithClientId:#"xxxxxx" clientSecret:#"xxxxxxx" poolId:#"us-east-1_xxxxxx"];
[AWSCognitoIdentityUserPool registerCognitoIdentityUserPoolWithConfiguration:serviceConfiguration userPoolConfiguration:configuration forKey:#"us-east-1_xxxxx"];
AWSCognitoIdentityUserPool *pool = [AWSCognitoIdentityUserPool CognitoIdentityUserPoolForKey:#"us-east-1_xxxxxx"];
pool.delegate = self;
return YES;
}
-(id<AWSCognitoIdentityPasswordAuthentication>) startPasswordAuthentication{
//implement code to instantiate and display login UI here
//return something that implements the AWSCognitoIdentityPasswordAuthentication protocol
NSLog(#"startpasswordauth AWS!");
return self.LoginViewController;
}
Also I did not understand this property line that's in the AWS github sample. The notation of *xxx I haven't see before. Here's the line:
#property (nonatomic, strong) AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails*> *passwordAuthenticationCompletion;
It's not mentioned in the tutorial, but without it
self.passwordAuthenticationCompletion.result = [[AWSCognitoIdentityPasswordAuthenticationDetails alloc] initWithUsername:self.userName.text password:self.password.text];
errors that the attribute is not found.
I have also tried this but delegate methods are not working.
Secondly, I tried with this code:
[AWSServiceManager.defaultServiceManager.defaultServiceConfiguration.credentialsProvider invalidateCachedTemporaryCredentials];
AWSCognitoIdentityUserPool *pool = [AWSCognitoIdentityUserPool CognitoIdentityUserPoolForKey:#"User"];
AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
self.user = [delegate.pool currentUser];
[[ self.user getSession:_userName.text password:_txtPassword.text validationData:nil ] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserSession *> * _Nonnull task) {
//success, task.result has user session
dispatch_async(dispatch_get_main_queue(), ^{
if(task.error || task.isCancelled) {
[[[UIAlertView alloc] initWithTitle:task.error.userInfo[#"__type"]
message:task.error.userInfo[#"message"]
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil] show];
}else {
AWSCognitoIdentityUserSession *session = (AWSCognitoIdentityUserSession *) task.result;
NSString *tokenStr = [session.idToken tokenString];
[[NSUserDefaults standardUserDefaults]setObject:tokenStr forKey:#"token"];
[[NSUserDefaults standardUserDefaults]synchronize];
[self performSelectorOnMainThread:#selector(pushToDashbard) withObject:nil waitUntilDone:YES];
}});
return nil;
}]
If I am passing the right credentials then this is giving the token, with wrong credentials giving no error response.
Hi, I have a slight issue. I have tried all types of solutions I could find, minus the outdated codes, on this topic of getting a UIWebView link to pop open Safari and load it there.
So far I can get the specific size to load in simulator, but every time I click it, it loads right there. I have to be missing a major step or I have the AppDelegate .h .m and ViewController .h .m completely messed up.
I was big into coding for devices up to 3rd Gen iPod/iPhones. I know that Xcode likes to update a lot and I have the 5.0.2 version. I am basically a No0b again, since I have been out of the game for some time.
Please let me know if you have any tips. Besides to give it up. lol. I know it can be done. Here is what I have...
#import "WIAppDelegate.h"
#implementation WIAppDelegate
- (BOOL)webview:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
// This practically disables web navigation from the webView.
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[request URL]];
return FALSE;
}
return TRUE;
}
#import <UIKit/UIKit.h>
#interface WIViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIWebView *webview;
#end
#import "WIViewController.h"
#interface WIViewController ()
#end
#implementation WIViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *fullURL = #"http://THESITE.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_webview loadRequest:requestObj];
}
#end
You need to implement the webview:shouldStartLoadWithRequest:navigationType: method on the class that acts as the UIWebViewDelegate
This should most likely live in your WIViewController class
#implementation WIViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *fullURL = #"http://THESITE.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_webview loadRequest:requestObj];
_webview.delegate = self;
}
- (BOOL)webview:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if (UIWebViewNavigationTypeLinkClicked == navigationType) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
#end
You will also need to ensure that you actually set this class as the UIWebViewDelegate I've down this as the last line of the viewDidLoad but you could hook this up in the xib if you prefer
I have been stumped by this Semantic Issue warning for a week now, and it is becoming frustrating.
Anyone willing to take a look at it? Any advice will be graciously taken. <3
WebViewController.m
#import "WebViewController.h"
#import "Reachability.h"
#implementation WebViewController
#synthesize webView;
#synthesize backbtn;
#synthesize forwardbtn;
#synthesize webAddy;
#synthesize activityIndicator;
#synthesize loadingLabel;
- (void)viewDidLoad {
loadingLabel.hidden = YES;
backbtn.enabled = NO;
forwardbtn.enabled = NO;
webView.scalesPageToFit = YES;
activityIndicator.hidesWhenStopped = YES;
if([Reachability currentReachabilityStatus] == NotReachable)
{
UIAlertView *av = [[[UIAlertView alloc]
initWithTitle:#"Sorry"
message:#"You are not connected to the internet. Please Try again"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] autorelease];
[av setDelegate:self];
[av show];
}
else
{
NSURL *url = [NSURL URLWithString:webAddy];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
}
[super viewDidLoad];
}
The Warning redirects me to the 20th line.
The compiler tells me:
"Class method '+currentReachabilityStatus" not found (return type defaults to 'id')"
If more information is needed, please let me know. Thanks again everyone!
See here.
The - (NetworkStatus) currentReachabilityStatus; is not a class method.
Use [[Reachability reachabilityForInternetConnection] currentReachabilityStatus] instead of [Reachability currentReachabilityStatus].
currentReachabilityStatus is an instance method, so you need an instance first.
I recently started an Xcode project, and its mostly web-based, in the sense it mostly works with UIWebView. I am a total noob at this. I would like to make an "No Internet Connection Alert". Basically An Alert that comes up if you have no internet connection. I have tried using the Reachability but since I'm such a noob, I didn't manage to figure ANYTHING out.. Heres my view controller:
This is my .h file: P.S: My WebView is called 'webone'.
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController
-(IBAction)refreshClicks:(id)sender;
#property (weak, nonatomic) IBOutlet UIWebView *webone;
#end
And This is My .m file:
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
#synthesize webone;
-(void)viewDidLoad {
NSURL *url = [NSURL URLWithString:#"http://www.lostcraft.net/mobile"];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[webone loadRequest:req];
[super viewDidLoad];
}
-(void)awakeFromNib{ //IGNORE
[self refreshClicks:self]; //IGNORE
}
-(IBAction)refreshClicks:(id)sender{//IGNORE
[webone loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.lostcraft.net/mobile"]]];//IGNORE
}
- (void)viewDidUnload
{
[self setWebone:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
Place this in your .m file
Under Your IBAction:
NSString *web = #"http://YOUR WEB ADRESS HERE";
NSURL *url = [NSURL URLWithString:web];
NSURLRequest *requestUrl = [NSURLRequest requestWithURL:url];
[webdone loadRequest:requestUrl];
Then somewhere in your .m
-(void)webView:(UIWebView *)webdone didFailLoadWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please check your internet connection" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
go into connections tab in interface builder in xcode
Right click from the delegate as shown in the picture (the top option) and drag it to your view contoller where you have your web view (webdone)
In viewDidLoad, I'm using NSURLRequest and NSURLConnection:
NSURLRequest *site_request =
[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com/"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
NSURLConnection *site_connection =
[[NSURLConnection alloc] initWithRequest:site_request delegate:self];
and then I use
-(void)connection:(NSURLConnection *)site_connection didReceiveData:(NSData *)data
{
site_response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
and I have the whole HTML in site_response.
I want to create an invisible UIWebView which will "open" the page from the NSURLRequest in order to use JavaScript to get content like this:
NSString *myText = [my_webView stringByEvaluatingJavaScriptFromString:
#"document.documentElement......"];
In my .h I have:
UIWebView *my_webview;
#property (nonatomic, retain) UIWebView *my_webview;
and in my .m I have:
#synthesize torrents_webview;
My viewDidLoad after NSURLRequest has
[my_webview loadRequest:site_request];
and I use
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
//an alertview here
}
in order to be sure it works. But nothing happens. It doesn't give an alert view.
What am I doing wrong?
webViewDidFinishLoad: is a method of the UIWebView delegate. You are not setting the delegate anywhere in the code you have shown.
#interface YourClass : UIViewController <UIWebViewDelegate>
...
- (void)loadView
{
self.webView.delegate = self;
}
...
- (void)dealloc
{
self.webView.delegate = nil;
}
Also if you use NSURLRequest you're going to get the page again. But there's no need to use NSURLConnection, just go straight to loading the UIWebVIew using the NSURLRequest.
Or if you must use NSURLConnection then when the file has downloaded save it to disk and use LoadHTMLString to load the contents.
ViewController.h
#interface TopTorrents_ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource,UIWebViewDelegate>
{
UIWebView *torrents_webview;
}
#property (nonatomic, retain) UIWebView *torrents_webview;
ViewController.m
#synthesize torrents_webview;
- (void)viewDidLoad
{
torrents_webview.delegate = self;
NSURLRequest *site_request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.gr/"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
[torrents_webview loadRequest:site_request];
[super viewDidLoad];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *myText = [torrents_webview stringByEvaluatingJavaScriptFromString:#"document.getElementsByTagName('body')[0]"];
UIAlertView *my_alert = [[UIAlertView alloc] initWithTitle:#"mytitle" message:myText delegate:nil cancelButtonTitle:#"my button" otherButtonTitles:nil,nil];
[my_alert show];
}
this is my updated code... thanks