i am trying to load a url in uiwebview in xcode and it is loading just fine but problem is that there is ZERO user interaction with it. i can not touch any button on it or can not even scroll it. i have already tried Allow Arbitrary Loads = YES in info.plist but nothing happened here is my code.
[webPage setDelegate:self];
[webPage loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://url.com"]]];
[webPage addSubview:activityIndicatorView];
here is more code from .h:
#interface ViewController : UIViewController<UIWebViewDelegate>{
IBOutlet UIWebView *webPage;
}
#property (retain, nonatomic) IBOutlet UIWebView *webPage;
its s simple uiwbview from interface builder in a simple uiviewcontroller.
and here is my info.plist
I figure out that problem might be here in this part of the code. there is a menu in my uinavigationbar as well which is loading xml menu. wait i will post my code.
- (void) makeMenu{
#try {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0),^{
NSURL *url=[NSURL URLWithString:#"http://url/xml-menu.php"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *error = nil;
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if ([response statusCode] >=200 && [response statusCode] <300)
{
rssOutputData = [[NSMutableArray alloc]init];
xmlParserObject =[[NSXMLParser alloc]initWithData:urlData];
[xmlParserObject setDelegate:self];
[xmlParserObject parse];
}
dispatch_async(dispatch_get_main_queue(), ^{
sideMenu.delegate = self;
NSInteger count;
NSMutableArray *itemsArry = [[NSMutableArray alloc] init];
count = [rssOutputData count];
for (int i = 0; i < count; i++){
BTSimpleMenuItem *item = [[BTSimpleMenuItem alloc]initWithTitle:[[rssOutputData objectAtIndex:i]xmltitle] image:[UIImage imageNamed:#"arrow.png"]
onCompletion:^(BOOL success, BTSimpleMenuItem *item) {
[webPage loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[[rssOutputData objectAtIndex:i]xmllink]]]];
}];
[itemsArry addObject:item];
}
NSArray *itemSarry=[[NSArray alloc] initWithArray:itemsArry];
sideMenu = [[BTSimpleSideMenu alloc]initWithItem:itemSarry addToViewController:self];
});
});
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
}
}
when i call this method in viewdidload uiwebview stop responding. And if i do not call this part uiwebview works just fine. please help me i need this menu as well.
Try this:
webPage.userInteractionEnabled = YES;
Related
I have a class where I request information from a provider class, in which after finalizing the job (asynchronous httpRequest block) needs to invoke a method [- (void) updateCountries] in the requester class. If I am not wrong this code worked in iOS 7, but now in iOS 8 it does not.
Can you please help me to understand why?
Methods in requester class:
- (void) viewWillAppear:(BOOL)animated {
//get countries to pickerView
webAPI = [[WebAPI alloc] init];
[webAPI retrieveCountries:self];
}
- (void) updateCountries {
//update countries content for pickerView
locationDAO = [[LocationDAO alloc] init];
countriesArray = [locationDAO getCountries];
[pickerView reloadAllComponents];
}
Lines in method in provider class where error happens:
SEL updateCountries = sel_registerName("updateCountries:");
[requester performSelectorOnMainThread:updateCountries withObject:nil waitUntilDone:YES];
If you need to checkout the entire method in the provider class, here it is:
- (void) retrieveCountries:(id)requester {
// NSLog(#"engine report: firing retrieveCountries http get");
NSString *urlAsString = kRetrieveCountriesListAPI;
NSURL *url = [NSURL URLWithString:urlAsString];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setTimeoutInterval:30.0f];
[urlRequest setHTTPMethod:#"GET"];
[urlRequest setValue:#"application/json" forHTTPHeaderField:#"Content-type"];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ([data length] >0 && error == nil){
NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"engine report: retrieveCountries server response: %#", response);
NSArray *level0 = [[NSArray alloc] initWithObjects:[NSJSONSerialization JSONObjectWithData:[[NSData alloc] initWithData:data] options:kNilOptions error:&error], nil];
NSArray *level1 = [level0 objectAtIndex:0];
LocationDAO *locationDAO = [[LocationDAO alloc] init];
[locationDAO deleteAllFromCountries];
for (int i = 0; i < [level1 count]; i++) {
CountryVO *countryVO = [[CountryVO alloc] init];
countryVO.myID = [[[level1 objectAtIndex:i] objectForKey:#"id"] integerValue];
countryVO.name = [[level1 objectAtIndex:i] objectForKey:#"country_name"];
[locationDAO saveCountryToDatabase:countryVO];
}
SEL updateCountries = sel_registerName("updateCountries:");
[requester performSelectorOnMainThread:updateCountries withObject:nil waitUntilDone:YES];
dispatch_async(dispatch_get_main_queue(), ^(void){
});
} else if ([data length] == 0 && error == nil){
NSLog(#"Nothing was downloaded.");
} else if (error != nil) {
NSLog(#"Error happened = %#", error);
} }];
}
THANK YOU A WHOLE LOT
Remove the : from the selector specification:
SEL updateCountries = sel_registerName("updateCountries");
Your method updateCountries doesn't take any arguments. So, when creating the selector, you should only write updateCountries (instead of updateCountries: which would indicate that this method takes an argument).
The reason why your app crashes is that when you try to perform this selector, the internals of your app are looking for a method called updateCountries on requester that takes one argument. This method doesn't exist, which is why the app crashes.
i am creating 2 buttons one for like and one for dislike when i click like button its disable and also disable dislike button same time.and so on. and its not change when i am run the application second time. i am implemented for that its work but problem is that when i run my application second time once again that button enable. problem is that i don't want that button same button enable.please help me what is the problem in my code
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:102/255.0
green:102/255.0 blue:204/255.0 alpha:1.0];
self.navigationController.navigationBar.titleTextAttributes =
#{NSForegroundColorAttributeName : [UIColor whiteColor]};
smsdisplaytext.editable=NO;
smsdisplaytext.backgroundColor= [UIColor colorWithRed:102/255.0 green:102/255.0
blue:204/255.0 alpha:1.0];
self.navigationItem.title=#"Insta SMS";
[ self getSmsData];
[self smsdisplay];
[self getLike];
}
-(void)sendlike
{
NSURL *url = [NSURL URLWithString:
#"http://sms.instatalkcommunications.com/apireq/AddRatingForSMS"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:[NSString stringWithFormat:#"%d",1] forKey:#"t"];
[request setPostValue:#"admin" forKey:#"h"];
[request setPostValue:[NSString stringWithFormat:#"%#",self.Id] forKey:#"cid"];
[request setPostValue:[NSString stringWithFormat:#"%d",1234567890] forKey:#"token"];
[request setPostValue:#"test#test.com" forKey:#"email"];
[request setTag:2];
[request setPostValue:#"true" forKey:#"like"];
[request setDelegate:self];
[request startAsynchronous];
}
-(void)senddislike
{
NSURL *url = [NSURL URLWithString:
#"http://sms.instatalkcommunications.com/apireq/AddRatingForSMS"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:[NSString stringWithFormat:#"%d",1] forKey:#"t"];
[request s etPostValue:#"admin" forKey:#"h"];
[request setPostValue:[NSString stringWithFormat:#"%#",self.Id] forKey:#"cid"];
[request setPostValue:[NSString stringWithFormat:#"%d",1234567890] forKey:#"token"];
[request setPostValue:#"test#test.com" forKey:#"email"];
[request setPostValue:#"false" forKey:#"Like"];
[request setTag:3];
[request setDelegate:self];
[request startAsynchronous];
}
- (void) requestFinished:(ASIHTTPRequest *)request
{
NSString *responseString = [request responseString];
responseString = [request responseString];
NSLog(#"%#",responseString);
if(request.tag==1)
{
SBJsonParser *parser = [[SBJsonParser alloc] init] ;
NSArray *jsondata = [parser objectWithString:responseString];
NSLog(#"%#",jsondata);
for (NSObject* item in jsondata)
{
likelabel.text = [[item valueForKey:#"Liked"] stringValue];
dislikelabel.text = [[item valueForKey:#"Disliked"] stringValue];
}
}
else if(request.tag==2)
{
[self getLike];
}
/////// getting comment
else if(request.tag==4)
{
// get comments
SBJsonParser *parser = [[SBJsonParser alloc] init] ;
NSMutableArray *jsondata = [parser objectWithString:responseString];
for(int i=0;i<jsondata.count;i++)
{
NSObject *temp = [jsondata objectAtIndex:i];
NSMutableDictionary *message = [[NSMutableDictionary alloc] init];
message[kMessageContent]=[temp valueForKey:#"Comment"];
message[#"Timestamp"]=[self dateWithJSONString:[temp valueForKey:#"CreatedDate"]];
last=[[temp valueForKey:#"Id"] integerValue];
[_chatController addNewMessage:message];
}
}
else
{
////post comment
[self getComment];
}
}
//this method for getting like and dislike
-(void)getLike
{
NSString *url = [NSString
stringWithFormat:#"http://sms.instatalkcommunications.com/apireq/GetRatingsForSMS?
t=1&h=admin&cid=%#&token=1234567890&email=test#test.com",self.Id];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
[request setRequestMethod:#"GET"];
[request setTag:1];
[request setDelegate:self];
[request startAsynchronous];
}
// here for like button
- (IBAction)btnlike:(id)sender
{
NSLog(#"keypress");
[self sendlike];
[self getLike];
UIButton *btnlike = (UIButton *) sender;
btnlike.enabled = NO;
UIButton *btndislike = (UIButton *) sender;
btndislike.enabled = NO;
}
//here i am action for dislike button
- (IBAction)btndislike:(id)sender
{
NSLog(#"keypress");
[self senddislike];
[self getLike];
UIButton *btndislike = (UIButton *) sender;
btndislike.enabled = NO;
_btnlike.enabled = NO;
}
#end
As I'm not an native english speaker, I hope I've understood correctly what you are trying to achieve.
If I understand correctly, You have a 'Like' and 'Dislike' buttons, and when the user presses on one of them, you want both to be disabled,
Which is working correctly for the current run.
But, if I understand correctly, the next time the app runs, the buttons are 'reset' to be enabled, and you don't want that,
You want the button be disabled every time the app runs.
If I did understood you correctly, the way to 'save' state of objects is using the NSUserDefaults.
You might have a better way to implement it than my example below, but it should do the trick, and also give you a better understanding on how to implement it, incase you need to modify my code.
Add the following method:
-(void)disableButtons {
[[NSUserDefaults standardUserDefaults] setBool: YES forKey: #"buttonsDisabled"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
now, at the end of the 'Like' and 'Dislike' buttons, just call the following methods by adding to your code:
[self disableButtons]
Now, add the following to viewDidLoad:
// someplace in viewDidLoad
BOOL bottunsDisabled = [[NSUserDefaults standardUserDefaults] boolForKey: #"buttonsDisabled"];
if(buttonsDisabled) {
self.btndislike.enabled = NO;
self.btnlike.enabled = NO;
}
The buttons defaults state are enabled, so the above code will change them, incase they have been disabled in previous runs.
Note that I also assumed you have a reference to the buttons (I assume you've created them in interface builder), if not, just create a property/ivar that will hold a reference to them.
And as Ian MacDonald mentioned above, in the 'Like' button method, you are disabling only the 'Like' button twice, and not disabling the 'Dislike' button.
In order to fix it, change the code to the following (again, I assume you have some sort of reference to both of them):
- (IBAction)btnlike:(id)sender
{
NSLog(#"keypress");
[self sendlike];
[self getLike];
self.btnlike.enabled = NO;
self.btndislike.enabled = NO;
[self disableButtons];
}
As I've said above, I'm not an native english speaker,
So I hope my answer was clear enough.
If something isn't clear, just tell me and I'll try to rephrase it.
Good luck mate!
Guys help deal with a problem I'm new to programming, and accordingly I have a problem in general, I do not know how to work with the network! I wrote a class in which I log into the site after login I can not use the connection to send other requests in other views!!!
here's what I wrote:
- (IBAction)loginClicked:(id)sender {
#try {
if([[txtUserName text] isEqualToString:#""] || [[txtPassword text] isEqualToString:#""] ) {
[self alertStatus:#"Пожалуйста заполните все поля!!!" :#"Авторизация не удолась!"];
} else {
NSString *post =[[NSString alloc] initWithFormat:#"login=%#&pass=%#",[txtUserName text],[txtPassword text]];
NSURL *url=[NSURL URLWithString:#"http://chgu.org/?mobile=1"];
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if ([response statusCode] >=200 && [response statusCode] <300)
{
NSData *responseData = [[NSData alloc]initWithData:urlData];
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
if([jsonObject objectForKey:#"error"])
{
[self alertStatus:#"Ошибка ввода данных" :#"Ю хав а трабл"];
} else {
[self alertStatus:#"Авторизация прошла успешно" :#""];
}
} else {
if (error) NSLog(#"Error: %#", error);
[self alertStatus:#"Connection Failed" :#"Login Failed!"];
}
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
[self alertStatus:#"Login Failed." :#"Login Failed!"];
}
[txtUserName resignFirstResponder];
[txtPassword resignFirstResponder];
}
how do I use this connection when I move to a different view!
Please tell me anything all night sitting at the computer can not figure out
You have the right idea, assuming that you want relatively tight coupling between these controllers via that delegate protocol.
Since neither controller knows about the other until that delegate property is set you need to have some object which has a reference to both of them wire up that relationship. In your case that's probably the application delegate which can create both controllers, set one as the delegate of the other, and pass both along to your tab bar controller.
What you might actually want is to have the app delegate give both controllers a reference to some shared model object. Your FirstViewController can update that model when you tap a button and your SecondViewController can observe changes to the model to update it's display (or just update its view when it appears based on the current model state). That way your controllers don't need to know anything about each other.
in secondVC, define something like the following:
#protocol secondVCDelegate
#interface secondVC : UIViewController
#property (nonatomic, assign) id<secondVCDelegate> delegate;
#end
#optional
-(void)someDelegateMethod:(secondVC*)viewController;
#end
at the time of creating the instance of secondVC you must assign the delegate property of secondVC to self! something like this:
// in firstVC
secondVC vc = [[secondVC alloc]...];
vc.delegate = self;
[navcontroller pushVC:vc];
the line vc.delegate = self; does the trick.
hope it helps...
In my code I am using an UIActivityIndicatorView on an UIAlertView. It is working fine but my problem is it is not showing up on correct time. I mean to say when the device get data from web service after that this loading indicator is appearing in the end and its not rite thing I think because I want it to be appear when the web service is sending or receiving data.
I need help as I am new to iOS app development. If there is any other easy way to do this thing then suggest me.
I hope my question is clear, my problem is according to this code the loading indicator is appearing after i get reply from web service but i want to run this indicator as the user will press update button and web service should be called after that. Tell me where i am wrong.
Here is the code I am using
-(IBAction)update:(id)sender
{
av=[[UIAlertView alloc] initWithTitle:#"Updating Image..." message:#"" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
ActInd=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[ActInd startAnimating];
[ActInd setFrame:CGRectMake(125, 60, 37, 37)];
[av addSubview:ActInd];
[av show];
{
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
int gid=[defaults integerForKey:#"gid"];
NSString *gameid=[NSString stringWithFormat:#"%i", gid];
NSLog(#"%#",gameid);
img=mainImage.image;
NSData *imgdata=UIImagePNGRepresentation(img);
NSString *imgstring=[imgdata base64EncodedString];
NSLog(#"%#",imgstring);
NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)imgstring,
NULL,
CFSTR("!*'();:#&=+$,/?%#[]"),
kCFStringEncodingUTF8);
NSLog(#"escapedString: %#",escapedString);
#try
{
NSString *post =[[NSString alloc] initWithFormat:#"gid=%#&image=%#",gameid,escapedString];
NSLog(#"%#",post);
NSURL *url=[NSURL URLWithString:#"http://mywebspace/updategameimage.php"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Response code: %d", [response statusCode]);
if ([response statusCode] >=200 && [response statusCode] <300) {
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
SBJsonParser *jsonParser = [SBJsonParser new];
NSDictionary *jsonData = (NSDictionary *) [jsonParser objectWithString:responseData error:nil];
NSLog(#"%#",jsonData);
NSInteger type = [(NSNumber *)[jsonData objectForKey:#"type"] integerValue];
NSLog(#"%d",type);
if (type==1) {
[self alertStatus:#"You can Keep on Drawing" :#"Sketch Updated"];
}
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
[self alertStatus:#"Unable to connect with game." :#"Connection Failed!"];
}
}
[av dismissWithClickedButtonIndex:0 animated:YES];
[av release]; av=nil;
}
UI updates are done on main thread. You have started activity indicator on main thread.It's fine.
Now, you are making synchronous network call on main thread. It should be asynchronous. Here until you will receive the response from network call, your main thread will remain busy and your UI will not be updated.
To update the UI, you can either make the network call asynchronous or you can start the activity indicator in a separate function and then delay the call of network activity by performselector:afterdelay method.
You can use GCD, Raywenderlich Tutorial
-(IBAction)update:(id)sender
{
/*
Setup indicator and show it
*/
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
/*
Do network call
*/
dispatch_async(dispatch_get_main_queue(), ^{
/*
Update UI
*/
});
});
}
Suppose i have two classes A & B. class A calls the asynchronus method Foo in class B. Foo method fetches data using asynchronous ASIHTTPRequest and send the data from Foo back as the return value to Class A. Class A will use that returned data and do the things
I am creating a object of my class URLParser here in another class and calling the function getJsonUrl , it will parse and get the json url for me . I am using that returned URL in another ASIHTTPRequest here . But i am getting EXC_BAD_ACCESS ...help me to figure it out ....
......
URLParser *urlParser = [[URLParser alloc] init];
NSString *JsonString = [urlParser getJsonUrl:#"http://mywebs.com/?q=iphone/news"];
NSLog(#" url returned = %#" ,JsonString);
NSURL *JsonUrl = [NSURL URLWithString:JsonString];
newsRequest = [ASIHTTPRequest requestWithURL:JsonUrl];
[newsRequest setDelegate:self];
[newsRequest startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
newsDictionary = [[NSMutableDictionary alloc] init];
NSData *responseData = [request responseData];
NSString *response = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding] ;
self.newsDictionary = [response JSONValue];
[response release];
[self getDataNews:self.newsDictionary];
}
URL Parser Class
#synthesize albumDic;
#synthesize GlobalRequest;
-(NSString*)getJsonUrl:(NSString *)url{
GlobalRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
[GlobalRequest setDelegate:self];
[GlobalRequest startAsynchronous]; // when i called the [GlobalRequest startSynchronous] ....both cases m getting the same error
return JsonStr;
}
- (void)requestFinished:(ASIHTTPRequest *)request{
albumDic = [[NSMutableDictionary alloc] init];
NSData *responseData = [request responseData];
NSString *response = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding] ;
self.albumDic = [response JSONValue];
[response release];
[self GetDictionary:self.albumDic];
}
- (void)requestFailed:(ASIHTTPRequest *)request{
[request cancel];
}