So i work with UICollectionView with my JSON. I write this code for parse, but i am not understand for why it's not work. My JSON have ([jsontest2] after key "imageMain").
So i paste my code, please help me:
#property (nonatomic,strong) NSMutableArray *patternImagesArray;
#end
#implementation ViewController
#synthesize patternImagesArray = _patternImagesArray;
NSURLConnection *connection;
NSMutableData *webdata;
Try to get data from JSON:
-(void) viewDidLoad{
_patternImagesArray = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"site"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (connection) {
webdata = [[NSMutableData alloc]init];
}
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webdata setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webdata appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
JSON parse:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSDictionary *allDataDictionary = [NSJSONSerialization JSONObjectWithData:webdata options:0 error:nil];
NSArray *tmp =[allDataDictionary objectForKey:#"jsontest2"];
if (tmp.count>0){
for (NSDictionary *diction in tmp) {
[self.patternImagesArray addObject:diction];
}
NSLog(#"%#", self.patternImagesArray);
}
[self.collectionView reloadData];
}
Some customize things:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
PatternView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"PatternCell" forIndexPath:indexPath];
NSString *myPatternString = [[self.patternImagesArray objectAtIndex:indexPath.row] valueForKey:#"thumb"];
NSLog(#"myPatternString %#",myPatternString);
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:myPatternString]];
cell.patternImageView.image = [UIImage imageWithData:data];
return cell;
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [self.patternImagesArray count];
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(100.0, 100.0);
}
You are abusing the variable "array" for two totally different purposes.
The underlying reason is that you haven't bothered to find reasonable names for variables. "array" is actually a global variable. It's not only accessible from any code within your file, but from any code anywhere in your program. Look at this bit of code:
NSDictionary *allDataDictionary =[NSJSONSerialization JSONObjectWithData:_webdata
options:kNilOptions error:nil];
array =[allDataDictionary objectForKey:#"jsontest2"];
for (array in allDataDictionary) {
}
You first parse the JSON data to allDataDictionary (you don't bother checking for errors). You access one key "jsontest2" from the dictionary and store it into the global variable "array". Whatever was in "array" before is now gone.
Then you have a for-loop, using the same global variable as the loop variable! That's total nonsense. But you also need to realise that this will iterate over the keys in your dictionary, so array is now an NSString and not an array anymore.
After that your code gets worse...
Go through your code line by line. Every line, think about what it is doing. There are many severe problems there.
Related
I'm a beginner in the area to work with database on iOS. However I could find a way to connect to a MySQL database, download and parse the json feed. Now in iOS 9, I can't use NSURLConnection anymore, that's why I have to replace it with NSURLSession. I saw many tutorials for example this here. So far, I was not able to replace it. Because I'm under time pressure, I can't waste more time to do this. Is here anyone who could help me to replace it?
My code looks exactly like this:
- (void)downloadItems
{
// Download the json file
NSURL *jsonFileUrl = [NSURL URLWithString:#"http://myhost.ch/test.php"];
// Create the request
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:jsonFileUrl];
// Create the NSURLConnection
[NSURLConnection connectionWithRequest:urlRequest delegate:self];
}
#pragma mark NSURLConnectionDataProtocol Methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// Initialize the data object
_downloadedData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the newly downloaded data
[_downloadedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// Create an array to store the locations
NSMutableArray *_locations = [[NSMutableArray alloc] init];
// Parse the JSON that came in
NSError *error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:_downloadedData options:NSJSONReadingAllowFragments error:&error];
// Loop through Json objects, create question objects and add them to our questions array
for (int i = 0; i < jsonArray.count; i++)
{
NSDictionary *jsonElement = jsonArray[i];
// Create a new location object and set its props to JsonElement properties
Location *newLocation = [[Location alloc] init];
newLocation.idS = jsonElement[#"idStatistic"];
newLocation.temp = jsonElement[#"temp"];
newLocation.hum = jsonElement[#"hum"];
newLocation.date_time = jsonElement[#"date_time"];
// Add this question to the locations array
[_locations addObject:newLocation];
}
// Ready to notify delegate that data is ready and pass back items
if (self.delegate)
{
[self.delegate itemsDownloaded:_locations];
}
}
You can try this,
{
NSURL *url = [NSURL URLWithString:#"http://myhost.ch/test.php"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
[theRequest setHTTPMethod:#"POST"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:theRequest
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"Result:%#", responseDict);
}];
[task resume];
}
json is:
{
"Title":"Kick", "Year":"2009", "Rated":"N/A", "Released":"08 May 2009",
"Runtime":"N/A", "Genre":"Comedy, Romance, Thriller", "Director":"Reddy Surender",
"Writer":"Abburi Ravi (dialogue), Reddy Surender (screenplay), Vakkantham Vamsi (story)",
"Actors":"Ravi Teja, Ileana, Shaam, Ali",
"Plot":"A guy with an abnormal lifestyle tries to find thrill and pleasure in every work he does and finally becomes a thief.",
"Language":"Telugu", "Country":"India", "Awards":"1 nomination.",
"Poster":"N/A","Metascore":"N/A",
"imdbRating":"7.6",
"imdbVotes":"736",
"imdvid":"tt1579592",
"Type":"movie",
"Response":"True"
}
The Code is:
-(void)parseData:(NSData *)data
{
NSString *responseString = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(#"responseString %#",responseString);
NSError *error;
NSArray *json = [NSJSONSerialization JSONObjectWithData:data
options:(kNilOptions)
error:&error];
NSLog(#"json data == %#", json);
NSMutableArray *response =[[NSMutableArray alloc]init];
for (int i = 0; i < json.count; i++)
{
response = [json valueForKey:#"imdbRating"];
User * userObj = [[User alloc]init];
userObj.movieRating = [json valueForKey:#"imdbRating"];
[response addObject:userObj];
}
[delegate getIMDBMovie_Rating:response];
}
How to save data in bussiness model object for key imdbRating
The Json you specified is not an array. This is an NSDictionary object. Also as this is a NSDictionary you don't need to use for loop.
Second thing you are doing wrong with your response variable.
you did:
response = [json valueForKey:#"imdbRating"];
User * userObj = [[User alloc]init];
userObj.movieRating = [json valueForKey:#"imdbRating"];
[response addObject:userObj];
here response variable is not an array even though you allocated it as NSMutableArray earlier. As you assign new value in response in the line: response = [json valueForKey:#"imdbRating"];
your variable type will be either NSNumber or NSString based on the type of [json valueForKey:#"imdbRating"].
So remove the line response = [json valueForKey:#"imdbRating"]; and it will work.
By doing this you will hv an array of User objects containing imdbRatings.
UPDATE
According to your comment your code has:
-(void)getIMDBMovie_Rating:(NSMutableArray*)retrievedData {
if (retrievedData.count > 0)
{
userObj = [retrievedData objectAtIndex:0];
NSLog(#"%#is the value",retrievedData);
iMDB_MovieRatingLabel.text=userObj.movieRating;
}
}
Problem is in your getIMDBMovie_Rating. as your method is accepting NSMutableArray as parameter. But when you supply value for your method is NSDictionay [delegate getIMDBMovie_Rating:response]; (you can check by NSLog(#"%#", [response class]);).
So in your getIMDBMovie_Rating method you are accessing [retrievedData objectAtIndex:0];. objectAtIndex is not available with NSDictionay that's why your app get crash.
Try like this,
-(void)parseData:(NSData *)data
{
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"responseString %#",responseString);
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:(kNilOptions) error:&error];
NSLog(#"json data == %#", json);
NSMutableArray *response =[[NSMutableArray alloc]init];
NSArray *aArray = [json valueForKey:#"imbdRating"];
for (NSDictionary *dictionary in aArray)
{
/* Create a initWithData method in your User Model class and pass the dictionary object to it like,
- (id) initWithData:(NSDictionary *) jsonDictionary
{
self=[super init];
if(self)
{
self.movieRating =[json valueForKey:#"imdbRating"];
} */
User * userObj = [[User alloc]initWithData:dictionary];
[response addObject:userObj];
}
[delegate getIMDBMovie_Rating:response];
}
Im having issues with this code reading some .json files, it works fine on json that can be read via IE like a webpage but wont work on files that the url is tring to download them like a ftp style.
In the end im looking at populating labels with the json info once this works but cant see what around the URLRequest is causing it.
This is what code im testing it with:
// WDViewController.h
#import <UIKit/UIKit.h>
#interface WDViewController : UIViewController{
NSArray *jsonArray;
NSMutableData *data;
}
#property (weak, nonatomic) IBOutlet UILabel *outputLabel;
-(IBAction)WDPlayerButtonUpdate:(id)sender;
#end
// WDViewController.m
#import "WDViewController.h"
#interface WDViewController ()
#end
#implementation WDViewController
#synthesize outputLabel;
-(IBAction)WDPlayerButtonUpdate:(id)sender{
NSURL *url = [NSURL URLWithString:#"http://gooruism.com/feed/json"];
NSURLRequest *data = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
data = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
// Loop through jsonArray
for (int i = 0; i< jsonArray.count; i++)
{
outputLabel.text = [[jsonArray objectAtIndex:i] objectForKey:#"889"]; // Set Labels
}
}
#end
The json file and url are just one that I found looking for a solution via Google and are only for testing.
After a lot more Google and learning some more about json,
Ive got the code working.
Ended up being more of a null exemption from empty indexes and not calling objectForKeys correctly, as was leaving strings that errored when then using to populate a label.
Code I finally got to work:
//
// WDViewController.m
// JSON Test
#import "WDViewController.h"
#interface WDViewController ()
#end
#implementation WDViewController
#synthesize testLabel;
-(IBAction)WDPlayerButtonUpdate:(id)sender
{
// Set network activity indicator
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// Set json url.
NSURL *url = [NSURL URLWithString:#"<url for json>"];
// get the url page into the nsdata object.
NSData *jsonData = [NSData dataWithContentsOfURL:url];
// Read json (from jasondata) and convert to object.
if ( jsonData != nil)
{
NSError *error = nil;
id result = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
if (error == nil)
NSLog (#"%#", result);
NSLog(#"Test 1");
// Retrieve array and show in log
NSLog(#"From status index: %#", [result objectForKey:#"status"]);
// Retrieve data and log
NSLog(#"From profile.handle index: %#", [[result objectForKey:#"profile"]objectForKey:#"handle"]);
NSLog(#"Next Test 2"); // Populate label with data handle
yestLabel.text = [[result objectForKey:#"profile"]objectForKey:#"handle"];
NSLog(#"End of Tests");
}
}
#end
I am currently writing an iPhone application that will push a username and password to a website to retrieve the HTML source code of the page which loads. I include login information in NSString *post.
When I NSLog the _responseData instance variable in the connectionDidFinishLoading method, the console prints a long series of eight digit hexadecimal numbers which I assume are some type of address or encrypted HTML (3c21444f 43545950 45206874 6d6c2050 55424c49 4320222d 2f2f5733...).
What should I do to convert/decrypt the addresses into HTML code or otherwise retrieve the HTML code of the webpage which loads?
My ViewController conforms to the NSURLConnectionDelegate protocol and includes the following code:
#interface ViewController : UIViewController<NSURLConnectionDelegate>
{
NSMutableData *_responseData;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// A response has been received, this is where we initialize the instance var you created
// so that we can append data to it in the didReceiveData method
// Furthermore, this method is called each time there is a redirect so reinitializing it
// also serves to clear it
_responseData = [[NSMutableData alloc] init];
NSLog(#"Received response");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data to the instance variable you declared
NSLog(#"Received data");
[_responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
// Return nil to indicate not necessary to store a cached response for this connection
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
//NSString *html=[NSString stringWithContentsOfURL:[NSURL URLWithString:#"https://grades.bsd405.org/Pinnacle/Gradebook/InternetViewer/GradeSummary.aspx?&EnrollmentId=770595&TermId=127463&ReportType=0&StudentId=114040"] encoding:NSASCIIStringEncoding error:nil];
NSLog(#"Finished loading");
//PRINT HTML:
NSLog(#"Data: %#",_responseData);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// The request has failed for some reason!
// Check the error var
NSLog(#"Failed to load");
}
- (IBAction)goPressed:(UIButton *)sender {
NSString *post = #"__LASTFOCUS&__EVENTTARGET&__EVENTARGUMENT&__VIEWSTATE=/wEPDwUJNTkxNzI3MDIzD2QWAmYPZBYCA
gMPZBYGAgEPZBYCAgkPZBYCAgEPZBYIAgMPFgIeB1Zpc2libGVoZAIFDxYCHwBoZAIHDxYCHwBoZAIJDxYCHgVzdH
lsZQUjdmVydGljYWwtYWxpZ246bWlkZGxlO2Rpc3BsYXk6bm9uZTtkAgMPDxYCHwBoZGQCBQ9kFghmD2QWAgINDxY
CHgVjbGFzcwUQc2luZ2xlU2Nob29sTGlzdBYCAgEPZBYCAgEPEGQPFgFmFgEQBQ5EZWZhdWx0IERvbWFpbgUIUGlu
bmFjbGVnZGQCAg9kFgICEw9kFgICAQ9kFgICAQ8QZGQWAGQCBw8PFgIeBFRleHQFIFBpbm5hY2xlIEdyYWRlIDIwM
TIgV2ludGVyIEJyZWFrZGQCCA8PFgIfAwU3Q29weXJpZ2h0IChjKSAyMDEzIEdsb2JhbFNjaG9sYXIuICBBbGwgcm
lnaHRzIHJlc2VydmVkLmRkZP/l6irI9peZfyqpKjk3fwLuEbos&__EVENTVALIDATION=/wEWBgKjnbqUCQLnksmg
AQKTpbWbDgLB5+KIBAL4xb20BAK20ZqiCel6sQLBsF1W3XHOxpgq+tJj+Rx2&ctl00$ContentPlaceHolder$Use
rname=TESTUSERNAME&ctl00$ContentPlaceHolder$Password=TESTPASSWORD&ctl00$ContentPlaceHolde
r$lstDomains=Pinnacle&ctl00$ContentPlaceHolder$LogonButton=Sign
in&PageUniqueId=2dacba26-
bb0d-412f-b06a-e02caf039c4b";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"https://grades.bsd405.org/Pinnacle/Gradebook/Logon.aspx?ReturnUrl=%2fPinnacle%2fGradebook%2fDefault.aspx"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[NSURLConnection connectionWithRequest:request delegate:self];
}
The NSLog of your NSData displays the object's description, which a hexadecimal string of the underlying binary data:
3c21444f 43545950 45206874 6d6c2050 55424c49 4320222d 2f2f5733 ...
Translates to a string of
<!DOCTYPE html PUBLIC "-//W3 ...
To get the NSString from the NSData, you do:
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
I have this url: http://maps.google.com.br/maps/api/directions/json?origin=porto+alegre&destination=novo+hamburgo&sensor=false
And this code:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSMutableDictionary *theDictionary = [responseString JSONValue];
NSLog(#"%#", theDictionary);
[responseString release];
if (theDictionary != nil)
{
NSArray *routesArray = [theDictionary objectForKey:#"routes"];
NSDictionary *firstRoute = [routesArray objectAtIndex:0];
NSArray *legsArray = [firstRoute objectForKey:#"legs"];
NSDictionary *firstLeg = [legsArray objectAtIndex:0];
steps = [firstLeg objectForKey:#"steps"];
}
[tableView reloadData];
}
I want to display every single #"html_instructions" on a uitableview.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self.steps count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cachedCell"];
if (cell == nil)
cell = [[[UITableViewCell alloc]
initWithFrame:CGRectZero reuseIdentifier:#"cachedCell"] autorelease];
return cell;
}
What's missing in my code??? Should be some little detail... any help would be GREAT!
I would do it like this:
Create url request with your url
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:[NSURL URLWithString:#"http://maps.google.com.br/maps/api/directions/json?origin=porto+alegre&destination=novo+hamburgo&sensor=false"]];
then create NSData structure, that holds response to the request and I converted it to string
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; //Or async request
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
After that, you load JSON into Dictionary, then to move one level down, pass it to another dictionary (result 1)
NSError *error=nil;
result = [NSJSONSerialization JSONObjectWithData:returnData options:kNilOptions error:&error];
result1 = [result objectForKey:#"routes"];
result2 = [result1 objectForKey:#"legs"];
Then move it into NSMutableArray
jsonMutArray= [result2 objectForKey:#"steps"];
From there, you just put label into your custom cell attach it as a IBOutlet, synthetize and do in cellForRowAtIndexPath method
cell.yourLabel.text = [jsonMutArray objectForKey:#"html_instructions"];
However, keep in mind, that I'm just begginer, so this might not be the most effective way of doing it :) Good Luck!
Don't you need to be doing something like this in your CellForRowAtIndexPath ?
NSString *cellValue = **WHATEVER VALUE YOU WANT TO PUT IN**;
cell.textLabel.text = cellValue;
return cell;
I don't see you adding your data to the cell.