multipart / x-mixed-replace с iPhone SDK - PullRequest
2 голосов
/ 05 марта 2010

Я пытаюсь загрузить несколько изображений в ответ на один http-запрос. На стороне сервера (java) я использую многоярусный ответ oreilly, и я получаю свои данные в симуляторе iPhone в didReceiveData (примерно один вызов для каждого изображения) после вызова didReceiveResponse (также приблизительно один вызов для каждого изображения) в моем делегате. Проблема в этом примерно ... Кто-нибудь когда-нибудь умел правильно обрабатывать multipart / x-mixed-re с iPhone SDK? Если да, то какова лучшая стратегия здесь? Должен ли я играть с ожидаемой длиной? на стороне сервера? на стороне клиента? я должен ждать, пока я не получу все ... ммм, который даже не видел достаточно, поскольку вызовы didReceiveData происходят в случайном порядке (я спрашиваю picture1, picture2, и я иногда получаю picture2, picture1, даже если порядок на сервере соблюдается!). Должен ли я временно переходить между картинками на стороне сервера? Или я должен отказаться от multipart / x-mixed-replace? что будет самым легким тогда?

Это много вопросов, но я действительно застрял здесь! Спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 06 марта 2010

Я не уверен, каково ваше окончательное использование изображений, но предполагаемое назначение типа содержимого multipart / x-midex-replace для каждой полученной детали - полная замена ранее полученных ответов. Думайте об этом как о кадрах видео; за один раз отображается только одно изображение, а предыдущие отбрасываются.

Temporizing почти никогда не является надежным решением. Особенно на iPhone вы столкнетесь с невообразимым разнообразием сетевых ситуаций, и если полагаться на магическую задержку между кадрами, возможно, все еще время от времени произойдет сбой.

Поскольку у вас есть контроль над сервером, я бы рекомендовал отбросить составную часть. При отправке нескольких запросов на сервер убедитесь, что вы не блокируете основной поток вашего приложения для iPhone. Используйте NSOperations или альтернативную библиотеку HTTP (например, ASIHTTPRequest ), чтобы сделать операции извлечения изображений асинхронными.

0 голосов
/ 08 апреля 2010

Я сделал это успешно, используя этот код. Важно создать 2 буфера для получения ваших данных. Если вы используете только один, у вас будут проблемы с двойным доступом (доступ к потоку и доступ к jpg CODEC) и поврежденные данные JPG. Не стесняйтесь спрашивать меня о более подробной информации.

- (IBAction)startDowload:(id)sender {

    NSURL *url = [NSURL URLWithString:@"http://210.236.173.198/axis-cgi/mjpg/video.cgi?resolution=320x240&fps=5"];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];

    [req setHTTPMethod:@"GET"];
    /*
    I create 2 NSMutableData buffers. This points is very important.
    I swap them each frame.
    */
    receivedData = [[NSMutableData data] retain];
    receivedData2 = [[NSMutableData data] retain];
    currentData = receivedData;

    urlCon = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    noImg = YES;
    frame = 0;

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response
{
    // this method is called when the server has determined that it
    // has enough information to create the NSURLResponse

    // it can be called multiple times, for example in the case of a
    // redirect, so each time we reset the data.
    // receivedData is declared as a method instance elsewhere

    UIImage *_i;
    @try
    {
        _i = [UIImage imageWithData:currentData];
    }
    @catch (NSException * e)
    {
        NSLog(@"%@",[e description]);
    }
    @finally
    {
    }

    CGSize _s = [_i size];
    [imgView setImage:_i];

    [imgView setNeedsDisplay];
    [[self view] setNeedsDisplay];
}   
/*
Buffers swap
*/
    if (currentData == receivedData)
    {
        currentData = receivedData2;        
    }
    else
    {
        currentData = receivedData;     
    }

    [currendData setLength:0];
}



- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // append the new data to the currentData (NSData buffer)
    [currendData appendData:data];
}
...