Sunday, September 19, 2010

 

Of Zips and the Internet

So of late I've been working on adding the ability to download a complete snapshot of Wikitravel to my iTravel app. And I've finally got it working, for both Android and iPhone - but there was many a glitch along the way.

First off: downloading. Now that part's actually pretty easy. You know what's tricky? Working out whether you can download. Both Android and iPhone bury their "hey, am I connected to the Internet, and if so, how?" API facilities deep in their documentation.

To be fair, Android isn't so bad:

public static boolean CheckInternetConnection(Context context) {
if (context==null)
return false;
ConnectivityManager connec = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return ( connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnectedOrConnecting() ||
connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting() );
}


...straightforward enough, just not as well-documented as it could be.

The iPhone, though. Well. Sheesh. The way you actually do it is through seriously byzantine and messy C code. Because most people don't want to have to deal with that, Apple provides a reference implementation - but do they tell you about this anywhere in their documentation? No, they do not. Thank heavens for Stack Overflow, which pointed me to Reachability.

But wait, there's less: the old version has a very simple interface:

+(BOOL) serverReachable {
Reachability *reachability = [Reachability reachabilityWithHostName:@"http://itravelapp.appspot.com/"];
return [reachability currentReachabilityStatus]!=NotReachable;
}


but the new version requires you to set up a whole asynchronous notification framework. OK, so it probably works better, and it's not too onerous:


-(void) initiateReachability {
// check for internet connection
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];

internetReachable = [[Reachability reachabilityForInternetConnection] retain];
[internetReachable startNotifier];

// check if a pathway to my server exists
serverReachable = [[Reachability reachabilityWithHostName: @"itravelapp.appspot.com"] retain];
[serverReachable startNotifier];
}

+(void) initiateReachability {
[[self getInstance] initiateReachability];
}

- (void) checkNetworkStatus:(NSNotification *)notice
{
// called after network status changes

NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
internetActive = internetStatus != NotReachable;

NetworkStatus serverStatus = [serverReachable currentReachabilityStatus];
serverActive = serverStatus != NotReachable;
}

-(BOOL) serverReachable {
return serverActive;
}

+(BOOL) serverReachable {
return [[self getInstance] serverReachable];
}


But still, compare and contrast to the Android version above. Oh, Apple. Whatever were you thinking?

OK. So you've got the Internet. You've downloaded your zip files. (Yes, files, plural; one of my early problems is that both Androids and iPhones choke and die on 100MB zip files, due to their memory constraints. But five 20MB zip files, handled consecutively, no problem.)

Now how do you open them?

In Android, it's easy enough: java.util.zip.ZipFile and java.util.zip.ZipEntry. (In fact, it's easy - and fast - enough that I don't even unpack those files; I just access data from within them on the fly.) On the iPhone, though, although the libz.1.2.3.dylib zlib framework is provided, actually working with it requires some serious low-level C chops, and mine are rusty beyond belief.

But that's OK! Because others' aren't, and we live in an open-source world. I just went out and downloaded Karl Mostowski's truly excellent ZipKit framework, and used it. I had some trouble using it as a static library... so I gave up and just included his source in my project. And it worked like a charm. A diamond-studded, streamlined, memory-miserly charm. Thanks, Karl!

Here's an example of it in action:

-(void) doUnpacking {
[Util showActivity];
[self startProgressView];
self.title=@"Unpacking ...";
NSThread* unpackThread = [[NSThread alloc] initWithTarget:self selector:@selector(launchUnpacking) object:nil];
[unpackThread start];
[unpackThread release];
}

-(void) launchUnpacking {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

int zipFiles = [[Settings getBulkZipFiles] intValue];
if (zipFiles > 0)
[Settings setBulkUnpackedFiles:0];

for (int i=0; i < zipFiles; i++) {
NSString *titleString = [NSString stringWithFormat:@"Unpacking %d of %d", i+1, zipFiles];
[self performSelectorOnMainThread:@selector(setTitle:) withObject:titleString waitUntilDone:YES];
NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];
NSString *fileName = [NSString stringWithFormat:@"/iTravelDump%d.zip",i];
NSString *dumpPath = [[Util getBulkDownloadPath] stringByAppendingPathComponent:fileName];
ZKFileArchive *archive = [ZKFileArchive archiveWithArchivePath:dumpPath];
archive.delegate = self;
totalFiles = [archive.centralDirectory count];
currentFile=0;
[archive inflateToDirectory:[[Util getBulkDownloadPath] stringByAppendingPathComponent:@"temp"] usingResourceFork:NO];
archive=nil;
[pool2 release];
[Settings setBulkUnpackedFiles:[Settings getBulkUnpackedFiles]+totalFiles];
}

//done!
[self performSelectorOnMainThread:@selector(unpackingFinished) withObject:nil waitUntilDone:NO];
[pool release];
}

//ZKArchive delegate
- (void) onZKArchive:(ZKArchive *) archive willUnzipPath:(NSString *) path {
if (progressView) {
float currentLength = (float)++currentFile;
float totalSize = (float)totalFiles;
float fraction = (float)currentLength/totalSize;
[progressView setProgress:fraction];
}
}

-(void)unpackingFinished {
[Util stopShowingActivity];
[self stopProgressView];
[Settings setLastBulkUnpack:[NSDate date]];
[Settings save];
self.title=@"Unpacking Complete";
[self loadHTML];
}

Labels: , , , , ,


Comments:
Thanks for sharing this informative content.,
Leanpitch provides online training in Agile team facilitation during this lockdown period everyone can use it wisely.

Agile team facilitation

ICP ATF
 
Thanks for sharing this informative content.,
Leanpitch provides online training in Agile team facilitation during this lockdown period everyone can use it wisely.
Team facilitator Agile

Agile facilitator
 
Thanks for sharing this informative content.,
Leanpitch provides online training in Agile team facilitation during this lockdown period everyone can use it wisely.

Team facilitator in Agile

ICAGILE ATF

 
스포츠중계 Very interesting blog. Alot of blogs I see these days don't really provide anything that I'm interested in, but I'm most definately interested in this one. Just thought that I would post and let you know.


 
Amazing! Its really awesome paragraph, I have got much clear idea concerning from this post.
스포츠토토

 
카지노사이트 Pretty portion of content. I just stumbled upon your weblog and in accession capital to claim
that I acquire actually loved account your blog posts.
Anyway I’ll be subscribing in your augment and even I fulfillment you get admission to consistently fast.

 
This post might be useful to students searching for computer networking assignment help, also experts can use to add something new to their skills.
 
Great internet site! It looks very expert! 카지노사이트Keep up the
good work!


 
카지노사이트 I am regular visitor, how are you everybody?

This post posted at this web page is truly good.



 
Wonderful beat ! I would like to apprentice at the same
time as you amend your web site,토토 how can i subscribe for a weblog web site?
The account aided me a applicable deal. I were a
little bit acquainted of this your broadcast provided vivid clear concept


 
I'm no longer sure where you are getting your info, however good
topic. I must spend some time studying much more or working
out more. 토토 Thank you for excellent information I was
searching for this info for my mission.



 
You have a fantastic blog, and I really appreciate what you do for these websites. For my schooling, I needed something significant, and your blog gave it.
 
Glad to have found your page!! 먹튀검증 This is such great work!! Interesting to read for sure!!
 
While looking for articles on these topics, I came across this article on the site here. As I read your article, I felt like an expert in this field. I have several articles on these topics posted on my site. Could you please visit my homepage? 메이저놀이터순위

 
Impressive and attractive post. I really like your blog.
Kraken Wallet | Blockfi Credit Card
 
We provide a 360 cycle of application design, integration and management services.
 

Post a Comment

Subscribe to Post Comments [Atom]





<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]