Помогите с созданием NSURLConnection в пользовательском классе - PullRequest
0 голосов
/ 14 апреля 2011

Привет всем, я пытаюсь использовать Yahoo PlaceFinder, чтобы сделать обратное геокодирование для приложения, которое я делаю. Проблема в том, что мне нужно использовать NSURLConnection для вызова моей базы данных. Поэтому я решил создать пользовательский класс, который инициализируется широтой и долготой пользователя и хранит только строковую переменную, содержащую состояние, в котором находится пользователь.

Обновление следующего кода теперь работает нормально ....

Вот это .h

#import <Foundation/Foundation.h>
#import "CJSONDeserializer.h"

@interface StateFinder : NSObject 
{
    NSString *userState;
    NSURLConnection *connection;
}

-(id)initwithLatitude:(NSString *)latitude andLongitude:(NSString *)longitude;
@property (nonatomic, retain) NSString *userState;
@property (nonatomic, retain) NSURLConnection *connection;

@end

и .m

#import "StateFinder.h"

@implementation StateFinder

@synthesize userState;
@synthesize connection;

-(id)initwithLatitude:(NSString *)latitude andLongitude:(NSString *)longitude
{
    if(self = [super init])
    {
        NSString *lat = latitude;
        NSString *lon = longitude;

        NSString *stateURLFinder = [NSString stringWithFormat:@"http://where.yahooapis.com/geocode?q=%@,+%@&gflags=R&flags=J&appid=zqoGxo7k", lat, lon];

        //NSLog(stateURLFinder);

        NSURL *stateURL = [NSURL URLWithString:stateURLFinder];


        NSURLRequest *request = [[NSURLRequest alloc] initWithURL: stateURL];

        connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

        [request release];
    }
    return self;
}


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"didReceiveResponse");
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"didFinishLoading");
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError");
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
    // Store incoming data into a string
    NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(jsonString);
    // Yes, this is incomplete, but I was waiting for the method to fire before going
        // any further. This will at least show me the JSON data being returned from yahoo 
        // in string format so I can output it to the console via NSLog
}

- (void)dealloc 
{
    [userState release];
    [connection release];
    [super dealloc];
}

@end

Это текущий код, который я использую, и он отлично работает. Все, что я сделал, это включил методы connectionDidFinishLoading и didFailWithError в исходный код. Что касается соединения, которое было освобождено до того, как оно было установлено, я использовал приведенный выше код как есть, без ранее упомянутых методов, и ни один из didReceiveData / didReceiveResponse не срабатывал. Только когда эти 2 метода были включены, методы начали вызываться. Не уверен, как, не уверен, почему, но это было единственное изменение среди всех предложенных, которые работали Большое спасибо @Jiva DeVoe, @XJones, @jlehr и @Aby за все советы / подсказки / предложения!

Ответы [ 4 ]

4 голосов
/ 14 апреля 2011

На самом деле, я советую вам определенно не использовать sendSynchronousRequest.Вы всегда должны пытаться использовать асинхронную сеть, если разрабатываемое вами приложение не является приложением командной строки без цикла выполнения.

Я подозреваю, что ваша проблема может заключаться в том, что вы немедленно освобождаете соединение, поэтому оно никогда не будет получено.шанс бежать.Вы должны добавить переменную-член и хранить ее до тех пор, пока не получите ответ или что-то еще.

Бонусный совет:

Предположим, вы, вероятно, делаете это для iOS или Mac, инаписание приложений с графическим интерфейсом.Эти приложения имеют циклы запуска.Когда вы используете синхронную сеть, как предполагает предыдущий ответ, вы предотвращаете выполнение этого цикла запуска.Это означает, что если запрос занимает больше нескольких секунд, ваше приложение iOS будет убито ОС, и ваше приложение Mac будет не отвечать на запросы.Ни один из них не является хорошим результатом.

1 голос
/ 14 апреля 2011

Избавьтесь от строки:

[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

Как только вы инициализировали соединение с запросом, оно запускается автоматически.У вас есть и другие проблемы.Ваша реализация протокола NSURLConnectionDelegate неверна.Вам необходимо постепенно добавлять данные, полученные в connection:didReceiveResponse, к объекту NSMutableData.Вы можете преобразовать его в JSON в `connectionDidFinishLoading: '.

Что касается утечки памяти, освободите соединение в connectionDidFinishLoading: или connection:didFailWithError: Вы гарантированно получите одно, но не оба из них.

Все, что вам нужно знать, это здесь

[РЕДАКТИРОВАТЬ: добавлен образец кода NSURLConnection]

// Attach this to the touchUpInside event of a UIButton
// Note that all objects will be autoreleased
// Note that you can comment out any or all of the NSURLConnection delegate methods
// and the request will execute

- (IBAction)initiateRequest
{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL urlWithString:@"http://www.google.com"]];
    NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
}

- (void)connection:(NSURLConnection *)connection didRecieveData:(NSData *)date
{
    NSLog(@"connection:didReceiveData");
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"connection:didReceiveResponse:");
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"connectionDidFinishLoading:");
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"connection:didFailWithError:");
}
1 голос
/ 14 апреля 2011

Вы отправляете сообщение release на соединение, прежде чем оно сможет запустить; не делай этого Что касается JSON, строка, которую вы сказали, была возвращена с сервера , это JSON. Вы ожидали чего-то еще?

0 голосов
/ 15 апреля 2011

Спасибо XJones за предложение.Я не включил два метода didFinishLoading или didFailWithError после вставки в мой код, оба didReceiveResponse и didReceiveData оба начали срабатывать.Спасибо всем за советы, советы и предложения, и, надеюсь, это поможет кому-то еще в будущем.

...