NSData stored somewhere

2020-04-21 06:38发布

问题:

recently i created a post: NSData caching routine

But, now i want to be more specific in what i'm asking.

You see, i have "carousel", that is actually a scroll view having 7 images. When it first appear, it load images from internet and auto scrolling.

My problem is, i don't want to images be loaded every time it scroll. Luckily, there is some "cache" mechanics worked in background. So, when it load all images, then terminate app, then launch in without internet connection, all images are set already, so, it somehow load it from somewhere.

There is the code i use:

NSError *error;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", WEBSITE, mdl.imageSubUrl]] options:NSDataReadingUncached error:&error];;
NSLog(@"data size0? %lu", (unsigned long)data.length);

And that is. You may want to try it by yourself, loading some image, then restart app in airplane mode and check bytes length. There will be data, even when i search for it, and there is said, that dataWithContentsOfURL does not do any cache.

So, what i want is simply check, if there are data, and if it is, not download it. Something like this:

if (haveData){

self.ivPic.image = [UIImage imageWith:myData];

} else {


    NSError *error;
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", WEBSITE, mdl.imageSubUrl]] options:NSDataReadingUncached error:&error];;
    NSLog(@"data size0? %lu", (unsigned long)data.length);

}

Unfortunately, i don't know how to make such test (if there is data). Secondly, i'm not quite sure how to load stored data, instead of dataWithContentsOfURL, which will launch loading from host.

回答1:

If you were to do this yourself, you could create two-tier cache system, using NSCache and local file system. So,

  1. At app startup, instantiate a NSCache object.

  2. When you need to download an image, see if image is in NSCache.

  3. If not, see if image is in NSCachesDirectory folder in file system, if found here, but not in NSCache, make sure to update NSCache accordingly.

  4. If found in neither NSCache nor NSCachesDirectory, request it asynchronously from the network (using NSURLSession) and if you successfully found image, update both NSCache and NSCachesDirectory accordingly.

  5. BTW, upon UIApplicationDidReceiveMemoryWarningNotification, make sure to empty the NSCache.

That might look something like:

NSString *filename = [webURL lastPathComponent];
NSURL *fileURL;

// look in `NSCache`

NSData *data = [self.cache objectForKey:filename];

// if not found, look in `NSCachesDirectory`

if (!data) {
    NSError *error;
    NSURL *cacheFileURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:false error:&error];
    fileURL = [cacheFileURL URLByAppendingPathComponent:filename];
    data = [NSData dataWithContentsOfURL:fileURL];

    // if found, update `NSCache`

    if (data) {
        [self.cache setObject:data forKey:filename];
    }
}

// if still not found, retrieve it from the network

if (!data) {
    [[NSURLSession sharedSession] dataTaskWithURL:webURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            // handle error
            return;
        }

        UIImage *image = [UIImage imageWithData:data];

        // if image retrieved successfully, now save it
        if (image) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.cache setObject:data forKey:filename];
                NSError *fileError;
                [data writeToURL:fileURL options:NSDataWritingAtomic error:&fileError];
            });
        }
    }];
}

Having said all of this, I agree with the others that it's worth trying the UIImageView categories found in either SDWebImage and/or AFNetworking. They might do what you need, with far less work.



回答2:

  • Firstly you should check the type:
  • Got to this link: I given my answer here: Check type of class an NSData store?

    Hope this helps you.