Updating progress of UIProgressView. And Getting Better Saving Performance
Updating progress of UIProgressView. And Getting Better Saving Performance
- Subject: Updating progress of UIProgressView. And Getting Better Saving Performance
- From: Gustavo Pizano <email@hidden>
- Date: Mon, 6 Dec 2010 23:37:38 +0100
Hello.
My application is saving some data, and it takes a while to do it, it can be 1 second to 10 sec around.. Im doing some image processing, The thing is..
I send the saving operation in another thread using the NSThread + detachNewThreadSelector:toTarget:withObject: method, and in the main thread I update a UIActivityIndicator, and stop it when I receive the NSThreadWillExitNotification. The problem is that when it takes long to save, it may seem the app is somehow stuck, even the spinning indicator is running. I wanted to change the ActivityIndicator to a progressview, but then I can't make it work because the saving process not on the main thread, i think.. correct me if Im wrong, Im not so much familiar with multithreaded apps.
As for the saving process, what I do is the following.
I have a Parent view which contains subviews, these subviews are drawing images. The user can modify this images, (scale and rotate), so when I save i encode these views so it will save the view's transform, and then I archive the data I encoded for all these subviews.
Also at the same time Im taking a screenshot to create a thumbnail image of the "progress", so the user can reload it anytime.
the subviews are one Class Called ItemView, and these is what I did in the encoding methods
#pragma mark -
#pragma mark NSCoding Protocol Methods
-(void)encodeWithCoder:(NSCoder *)aCoder{
[super encodeWithCoder:aCoder];
//Serializing the image Ref
CFMutableDataRef url = CFDataCreateMutable(kCFAllocatorDefault, 0);
CFStringRef type = kUTTypePNG;
size_t count = 1;
CFDictionaryRef options = NULL;
CGImageDestinationRef dest = CGImageDestinationCreateWithData(url, type, count, options);
CGImageDestinationAddImage(dest, bc_itemImage, NULL);
CGImageDestinationFinalize(dest);
//Encodin teh image
NSData * data = (NSData *)url;
[aCoder encodeObject:data forKey:@"BCItemImageDataKeyName"];
//Release the dest
CFRelease(dest);
CFRelease(url);
}
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
bc_isSelected = bc_isInBox = bc_willMoveFromBox = NO;
//Deserializing the Image
NSData * data = [aDecoder decodeObjectForKey:@"BCItemImageDataKeyName"];
CFDataRef imgData = (CFDataRef)data;
CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData (imgData);
bc_itemImage = CGImageCreateWithPNGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
return self;
}
And this is the method that is called when excecting the NSThread detachNewThreadSelector method
-(void)saveProgress{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDirectory = [arrayPaths objectAtIndex:0];
NSString * thumDirectory = [arrayPaths objectAtIndex:0];
BOOL dir;
NSError * error, * error2;
if(![[NSFileManager defaultManager] fileExistsAtPath:[docDirectory stringByAppendingFormat:@"/Progress/"] isDirectory:&dir]){
NSLog(@"It doesn't exist");
[[NSFileManager defaultManager] createDirectoryAtPath:[docDirectory stringByAppendingFormat:@"/Progress/"]
withIntermediateDirectories:YES attributes:nil error:&error];
[[NSFileManager defaultManager] createDirectoryAtPath:[thumDirectory stringByAppendingFormat:@"/Thumbnails/"]
withIntermediateDirectories:YES attributes:nil error:&error2];
}
//Im gonna create a thumbView of the current progress,
UIImage * currentProgressImage = [self screenShotOfSceneView];
CGFloat thumbWidth, thumbHeiht;
if([currentProgressImage size].height > [currentProgressImage size].width){
thumbHeiht = 150.0f;
thumbWidth = 112.5;
}
else {
thumbHeiht = 112.5;
thumbWidth = 150.5;
}
UIImage * thumb = [UIImage imageWithImage:currentProgressImage scaledToSize:CGSizeMake(thumbWidth, thumbHeiht)];
//Archivign the thumbnails
NSKeyedArchiver *archiver;
NSMutableData * dataThumb = [NSMutableData data];
archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:dataThumb];
[archiver encodeObject:thumb forKey:@"BCProgressThumbnail"];
[archiver finishEncoding];
[archiver release];
//[bc_creationName release];
self.bc_creationName = progressToLoad != nil ? progressToLoad:[[NSDate date] description];
NSString *thumbPath = [docDirectory stringByAppendingString:[NSString stringWithFormat:@"/Thumbnails/%@.tmb",bc_creationName]];
BOOL okSavedThumb = [dataThumb writeToFile:thumbPath atomically:YES];
NSLog(@"Thumb Saved %i",okSavedThumb);
NSLog(@"Saving Items in Scene");
//locating app sandbox directory
NSData * dataOfItems = [(BCSceneView *)self.view archiveItemsInScene]; // The scene loops on all the items subviews and encodes them
NSLog(@"Finishin Saving");
//Now saving
//Getting the date
NSString *filePath = [docDirectory stringByAppendingString:[NSString stringWithFormat:@"/Progress/%@.bc",bc_creationName]];
BOOL okSaved = [dataOfItems writeToFile:filePath atomically:YES];
NSLog(@"Data Saved %i",okSaved);
[(BCSceneView*)self.view setBc_sceneHasChanges:NO];
self.progressToLoad = bc_creationName;
[pool drain];
}
So basically Im saving and creating the thumbnail in that thread, I think this can be done in 2 different threads, one that saves and that that creates the thumbnail, right?, any considerations to take in mind?, how can i improve saving time?
Thanks
Gustavo
PS:The decoding process is very fast., it takes no more than 2 seconds.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden