Что плохого в следующем URLConnection? - PullRequest
2 голосов
/ 01 апреля 2009

Смотри также:

Асинхронный веб-запрос Objective-C с файлами cookie

Я потратил день на написание этого кода, и кто-нибудь может сказать мне, что здесь не так?

WSHelper унаследован от NSObject, я даже пробовал NSDocument и NSObjectController и все такое.

-(void) loadUrl: (NSString*) urlStr{
    url = [[NSURL alloc] initWithString:urlStr];
    request = [NSURLRequest requestWithURL:url cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 60.0];
    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
    if(connection)
    {
        receivedData = [[NSMutableData data] retain];
            //[connection start];
    }
    else
    {       display error etc...   }
    NSApplication * app = [NSApplication sharedApplication];
    [app runModalForWindow: waitWindow];// <-- this is the problem...
}

-(void)connection: (NSURLConnection*)connection didReceiveData:(NSData*)data{
    progressText = @"Receiving Data...";
    [receivedData appendData:data];
}

-(void)connection: (NSURLConnection *)connection didFailWithError:(NSError *)error{
    progressText = @"Error...";
    NSAlert * alert = [[NSAlert alloc] init];
    [alert setMessageText:[error localizedDescription]];
    [alert runModal];
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    progressText = @"Done...";
    pData = [[NSData alloc] initWithData:receivedData];
    [self hideWindow];
}

Код просто ничего не делает, он вообще не прогрессирует. Я даже попробовал с / без startImmediately: ДА, но не повезло !!!, это выполняется в главном окне, поэтому даже поток и его цикл выполнения успешно работают.

Я попытался вызвать синхронный запрос, и он работает правильно !! Но мне нужно асинхронное решение.

Я добавил CoreServices.Framework в проект. Что еще я должен добавить в проект? какие-либо настройки компилятора? Или мне нужно что-то инициализировать, прежде чем я смогу использовать NSURLConnection?

Любое решение для запуска NSURLConnection в другом потоке в своих собственных NSRunLoop, Objective-C и MAC Development не содержит ни одного примера кода в документации, который бы затруднял кодирование.

Ответы [ 4 ]

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

Я также столкнулся с той же проблемой, что не вызывал метод делегата при использовании NSURLConnection в модальном окне.

после некоторого расследования, следующий код разрешит его.

NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:requst delegate:self startImmediately:NO];
[conn scheduleRunLoop:[NSRunLoop currentRunLoop] forMode:NSModalPanelRunLoopMode];
[conn start];

Однако, когда вызывается connectionDidFinishLoading, [NSApp stopModal] не работает, вместо этого необходимо вызвать [NSApp abortModal].

3 голосов
/ 02 апреля 2009

Во-первых, вы делаете запуск соединения слишком сложным. Изменить на:

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

Удалить [connection start]. Сейчас:

  • Ваше приложение определенно выполняет цикл выполнения нормально? NSURLConnection требует, чтобы это работало.
  • Можете ли вы выполнить синхронную загрузку запроса URL?
  • В отладчике вы видите, что url это то, что вы ожидаете? Что это?
  • Возможно ли, что вы освобождаете WSHelper до получения каких-либо сообщений делегата? NSURLConnection в конце концов является асинхронным.

Не нужно делать ничего особенного, чтобы использовать NSURLConnection, это простая часть фреймворка Foundation. Никаких специальных настроек компилятора не требуется. Нет инициализации перед использованием. Ничего такого. Пожалуйста, не начинайте слепо пробовать что-то вроде ввода CoreServices.Framework.

Поскольку синхронная отправка запроса работает, возможно, что-то не так с вашей обработкой асинхронного аспекта. Это может быть:

  • Runloop не работает в NSDefaultRunLoopMode, поэтому соединение не может планировать себя.
  • Какая-то другая часть вашего кода вызывает -cancel для соединения, прежде чем оно сможет загрузиться.
  • Вам удается освободить соединение до того, как оно сможет загрузиться.

Реальная проблема

Ах, на самом деле я только что понял, что происходит. Вы звоните:

-[NSApp runModalForWindow:]

Прочитайте описание того, что делает этот метод . Он не запускает цикл выполнения, как ожидает NSURLConnection. Я бы сказал, что на самом деле вы не хотите показывать окно, подобное этому, при запуске URL-соединения для него.

Я бы также предложил вам реализовать метод делегата -connection:didReceiveResponse:. Здесь вы хотите проверить, что сервер возвращает ожидаемый код состояния.

3 голосов
/ 03 апреля 2009

Вы говорите, что используете это в модальном диалоге? Модальное диалоговое окно переводит цикл выполнения в другой режим. Вы должны быть в состоянии заставить это работать, запланировав это для запуска в модальном диалоговом режиме цикла выполнения, в дополнение к нормальному режиму цикла выполнения. Попробуйте добавить эту строку кода после выделения connection в loadURL:

[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSModalPanelRunLoopMode];

Надеюсь, это поможет.

1 голос
/ 01 апреля 2009

Откуда ты знаешь, что он ничего не делает? Есть ли какие-либо сообщения об ошибках или предупреждения во время компиляции? Есть ли какие-либо сообщения об ошибках на консоли во время работы программы?

Вы пытались установить точки останова в своем коде и выполнить то, что, как вы ожидаете, происходит?

...