#iphone #json
#iPhone #json
Вопрос:
Я использую приведенный ниже код для использования json, но мне нужно больше URL-адресов на той же странице, как этого добиться, заранее спасибо
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
//do something with the json that comes back ... (the fun part)
}
- (void)viewDidLoad
{
[self searchForStuff:@"iPhone"];
}
-(void)searchForStuff:(NSString *)text
{
responseData = [[NSMutableData data] retain];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.whatever.com/json"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
Я использую php для веб-доступа
Ответ №1:
Вы могли бы использовать переменные экземпляра для хранения указателей на соединения. Затем в обратных вызовах делегатов проверьте равенство указателей, чтобы проверить, с каким соединением вы имеете дело.
Комментарии:
1. Что ж, могу я предложить вам сначала создать несколько простых вещей, освоить Objective C, возможно, следовать некоторым руководствам, а затем попробовать это самостоятельно ;). Или просто используйте отличное решение Dan Rays.
Ответ №2:
Поскольку NSValue соответствует NSCopying
, я использую его для переноса указателя на соединение и использую это как ключ для доступа к соответствующим данным из a NSMutableDictionary
. Например, вы можете сделать что-то вроде следующего:
-(void)searchForStuff:(NSString *)text withTarget:(id)target selector:(SEL)selector {
responseData = [[NSMutableData data] retain];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.whatever.com/json"]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:target,@"target",NSStringFromSelector(selector),@"selector",nil];
NSURLConnection *c = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[myMutableDictionary setObject:options forKey:[NSValue valueWithPointer:c]];
[c release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSValue *p = [NSValue valueWithPointer:connection];
NSDictionary *options = [myMutableDictionary objectForKey:p];
if (options) {
id target = [options objectForKey:@"target"];
SEL selector = NSSelectorFromString([options objectForKey:@"selector"]);
if (target amp;amp; selector amp;amp; [target respondsToSelector:selector]) {
[target performSelector:selector withObject:responseData];
}
}
}
Ответ №3:
Не делайте ничего из этого.
Вместо этого используйте блестящую библиотеку ASIHTTPRequest, которая делает все намного проще и лучше. Буквально, с тех пор как я открыл ASI пару лет назад, я не написал ни одного NSURLConnection, ни одного.
Блочный интерфейс ASI позволяет настраивать объект запроса с помощью его кода обработчика перед его запуском и устраняет необходимость в делегировании.
__block ASIHTTPRequest *r = [ASIHTTPRequest requestWithUrl:myNSURLObject];
[r setCompletionBlock:^{
NSLog([r responseString]); //for instance
}];
[r startAsynchronous];
Если вас пугают блоки, вы также можете указать конкретный запрос на определенный метод, чтобы разные типы запросов можно было обрабатывать отдельно:
- (void) viewDidLoad { //or wherever
ASIHTTPRequest *r = [ASIHTTPRequest requestWithUrl:myFirstURL];
r.delegate = self;
[r setDidFinishSelector:@selector(requestDone:)];
[r startAsynchronous];
}
// then later on...
- (void)requestDone:(ASIHTTPRequest *)request
{
NSString *response = [request responseString];
}
Комментарии:
1. Хотя мне нравится подход на основе блоков (и хотелось бы, чтобы NSURLConnection использовал его), я бы не стал использовать ASIHTTPRequest, потому что он больше не поддерживается разработчиком. Существуют аналогичные библиотеки, которые все еще поддерживаются. Более подробную информацию см. в блоге ASIHTTPRequest allseeing-i.com
2. @codecaffeine — Вау…. Я понятия не имел. Боже, я чувствую, что член семьи умер или что-то в этом роде. Фух. Думаю, придется начать искать замену. Я ни за что не вернусь к родной агонии.
3. Да, я думаю, что загрузка URL-адресов на основе блоков имеет больше смысла и проще. Я надеюсь, что Apple добавит что-то похожее на NSURLConnection. The allseeing-i.com в блоге упоминается пара альтернатив.
Ответ №4:
На самом деле вам не нужно больше одного делегата. Вам нужно более одного NSURLConnection, и вы можете проверить, какой из них вызывает метод делегирования.
Например. Предполагая следующую переменную экземпляра (или свойства):
NSURLConnection *connectionA;
NSURLConnection *connectionB;
NSMutableData *dataA;
NSMutalbeData *dataB;
Сначала вы создаете экземпляр каждой переменной NSURLConnection
-(void)searchA:(NSString *)text
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.a.com/%@", text]]];
connectionA = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
-(void)searchB:(NSString *)text
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.b.com/%@", text]]];
connectionB = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
Затем вы можете проверить, какое соединение вызывает метод делегирования, и настроить реализацию на основе этого соединения
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if (connection == connectionA) {
[dataA appendData:data];
}
else if (connection == connectionB) {
[dataB appendData:data];
}
}
Вам нужно будет сделать это для каждого метода делегирования.
Комментарии:
1. Вы можете записать все методы делегирования аналогично connection:didReceiveData: . Используйте «if … else if», чтобы настроить поведение на основе каждого соединения.