Разбор JSON-ссылки в Objective C ошибка
Я пытаюсь проанализировать файл JSON, содержащий URL-адреса изображений. Мой код:
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"http://my-site/pictureparse.php?name=Name"]];
NSData *data= [NSData dataWithContentsOfURL:URL];
if (data == nil) {
return;
}
NSError* error;
NSMutableDictionary *jsonIs = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
NSLog(@"Json : %@",jsonIs);
if (jsonIs != nil) {
NSString *item_media = [jsonIs objectForKey:@"link"];
где "ссылка" - ссылка на изображение в JSON-файле. Структура JSON выглядит следующим образом:
[
{
"link": "http://link-to-image.com/picture.jpg",
"title": "Title",
"published": "0:01 PM 24/10"
},
{
"link": "http://link-to-image.com/picture.jpg",
"title": "Title",
"published": "0:01 PM 24/10"
},
{
"link": "http://link-to-image.com/picture.jpg",
"title": "Title",
"published": "0:01 PM 24/10"
},
{
"link": "http://link-to-image.com/picture.jpg",
"title": "Title",
"published": "0:08 PM 23/10"
}
]
Когда я запускаю приложение, я вижу в NSLog, что оно анализирует объекты, но я получаю ошибку:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x16e81ed0
Как взять эти проанализированные объекты / ссылки и отобразить их в ленте, например в Instagram?
Я пытался с помощью следующего кода, но он не работает...
#import "PicturesViewController.h"
#import "DemoViewController.h"
#import "SecondViewController.h"
#import "AppDelegate.h"
#import "RNBlurModalView.h"
#import "PictureJSON.h"
#import "HMSegmentedControl.h"
@interface PicturesViewController ()
{
NSInteger refreshIndex;
NSArray *images;
}
@end
@implementation PicturesViewController
- (void)viewDidLoad
{
HMSegmentedControl *segmentedControl = [[HMSegmentedControl alloc] initWithSectionTitles:@[@"Instagram", @"Hashtags", @"Facebook"]];
[segmentedControl setFrame:CGRectMake(10, 10, 300, 60)];
[segmentedControl addTarget:self action:@selector(segmentedControlChangedValue:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:segmentedControl];
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Menu" style:UIBarButtonItemStyleBordered target:self action:@selector(showMenu)];
UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(swipeHandler:)];
[self.view addGestureRecognizer:gestureRecognizer];
[self issueLoadRequest];
}
- (void)swipeHandler:(UIPanGestureRecognizer *)sender
{
[[self sideMenu] showFromPanGesture:sender];
}
- (void)segmentedControlChangedValue:(HMSegmentedControl *)segmentedControl1 {
[self issueLoadRequest];
}
- (void)segmentedControlSelectedIndexChanged:(id)sender
{
[self issueLoadRequest];
}
#pragma mark -
#pragma mark Button actions
- (void)showMenu
{
[[self sideMenu] show];
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"PictureJSON";
PictureJSON *cell = (PictureJSON *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"PictureJSON" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// The element in the array is going to be a dictionary. I JUST KNOW THIS. The key for the tweet is "text".
NSDictionary *tweet = [self.tweets objectAtIndex:indexPath.row];
NSLog(@"%@", [cell class]);
UIImageView *instaImage = [[UIImageView alloc] init];
instaImage.image = [tweet objectForKey:@"link"];
cell.titleLabel.text = [tweet objectForKey:@"title"];
cell.timeLabel.text = [tweet objectForKey:@"published"];
return cell;
}
- (void)issueLoadRequest
{
// Dispatch this block asynchronosly. The block gets JSON data from the specified URL and performs the proper selector when done.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://my-site.com/picutreparse.php?name=Name"]];
[self performSelectorOnMainThread:@selector(receiveData:) withObject:data waitUntilDone:YES];
});
}
- (void)receiveData:(NSData *)data {
// When we have the data, we serialize it into native cocoa objects. (The outermost element from twitter is
// going to be an array. I JUST KNOW THIS. Reload the tableview once we have the data.
self.tweets = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
[self.myTableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tweets.count;
}
@end
Буду очень признателен за решение!
2 ответа
Что не так вы делаете NSMutableDictionary
NSMutableArray *jsonIs = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
NSLog(@"Json : %@",jsonIs);
if (jsonIs != nil) {
NSMutableDictionary* aDict = jsonIs[0];
NSString *item_media = [aDict objectForKey:@"link"];
}
ваш основной JSON - это массив, потому что в этом массиве "[...]" вы получили словари: "{..}"
редактировать для tableView вопрос:
сделать NSMutableArray *jsonIs
к глобальному
@implementation PicturesViewController{
NSMutableArray *jsonIs
}
тогда в табличном представлении делегат:
NSString *item_media = [jsonIs[indexPath.row] objectForKey:@"link"];
Проблема в том, что объект, который вы получаете при разборе, является NSArray
и не NSDictionary
,
Измените свой код на этот:
@interface PicturesViewController ()
{
// ...
NSArray *items;
}
В точке, где вы получаете данные:
items = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
В заключение:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// ...
NSDictionary *item = [items objectAtIndex:indexPath.row];
NSString *item_media = [item objectForKey:@"link"];
// ...
}