My azure blob is never returned, but no error is either

318 Views Asked by At

I have an IOS app using azure storage blobs for jpg photos. My issue is when retrieving the blobs for display.

Most of the time they are retrieved fine. But just occasionally an odd one will not be returned. Instead 749 bytes are returned but with error still = nil.

Now that would be fine, no problem really. However EVERY time after that when I try to retrieve that blob again then the same issue occurs. All the surrounding blobs are returned fine. The blob in question is fine and can be retrieved using another device.

I have spent lots of time clearing all variables involved and recalling the blob in question and no matter what only ever 749 bytes are returned. Deleting the app from the device and reinstalling it is the only workaround!

So I presume Azure storage or mobile services think the returned data was ok (since it had no error) and keeps sending the same - how can I prevent that and demand a true retry?

The actual retrieving code below was courtesy of github: thank you Ajayi13 it is almost awesome

    [request fetchDataWithBlock:^(NSData* data, NSError* error)
 {
     if(error)
     {
         if(block)
         {
             block(nil, error);
         }
         else if([(NSObject*)_delegate respondsToSelector:@selector(storageClient:didFailRequest:withError:)])
         {
             [_delegate storageClient:self didFailRequest:request withError:error];
         }
         return;
     }

     if(block)
     {
         block(data, nil);
     }
     else if([(NSObject*)_delegate respondsToSelector:@selector(storageClient:didGetBlobData:blob:)])
     {
         [_delegate storageClient:self didGetBlobData:data blob:blob];
     }
 }];

I have now added the following code based on AdamSorrin's response and a blog post BY DANIEL PASCO: https://blackpixel.com/writing/2012/05/caching-and-nsurlconnection.html

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {

NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)[cachedResponse response];

    // Look up the cache policy used in our request
    if([connection currentRequest].cachePolicy == NSURLRequestUseProtocolCachePolicy) {
        NSDictionary *headers = [httpResponse allHeaderFields];
        NSString *cacheControl = [headers valueForKey:@"Cache-Control"];
        NSString *expires = [headers valueForKey:@"Expires"];
        if((cacheControl == nil) && (expires == nil)) {
            NSLog(@"server does not provide expiration information and we are using NSURLRequestUseProtocolCachePolicy");
            return nil; // don't cache this
        }
    }
    return nil;
}

BUT this has not fixed my issue :o(

1

There are 1 best solutions below

4
On BEST ANSWER

I'm not sure exactly what networking library you're using (your request object), so I'm going to assume that it's based off of NSURLSession and NSURLRequest. If not, the details here will be wrong, but the underlying reason still might be correct.

I would guess that your problem is two-fold.

  • For NSURLSession downloadTaskWithRequest:completionHandler:, the NSError parameter passed into the completion handler block is set only for client-side errors. Retryable service-side errors (throtting, server busy, etc.) aren't detected as such on the client - you need to look at the HTTP response code/message and handle appropriately.

  • Look at the NSURLSessionConfiguration documentation, specifically requestCachePolicy. My guess is that you're getting stale data from the cache when you try and re-fetch the contents of the blob. You can use this parameter to force the request to re-fetch the data from the service, if this is indeed causing the problem.