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:@""];
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: @""] 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: and (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:@"/",i];
NSString *dumpPath = [[Util getBulkDownloadPath] stringByAppendingPathComponent:fileName];
ZKFileArchive *archive = [ZKFileArchive archiveWithArchivePath:dumpPath];
archive.delegate = self;
totalFiles = [archive.centralDirectory count];
[archive inflateToDirectory:[[Util getBulkDownloadPath] stringByAppendingPathComponent:@"temp"] usingResourceFork:NO];
[pool2 release];
[Settings setBulkUnpackedFiles:[Settings getBulkUnpackedFiles]+totalFiles];

[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: , , , , ,

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


스포츠중계 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.

Great internet site! It looks very expert! 카지노사이트Keep up the
good work!

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!!
We provide a 360 cycle of application design, integration and management services.
dressing room virtual You can go further and make a consistency check by retrieving all t-shirts from the Item.
Assignment help is an in-depth study of criminal punishment, whereas criminal justice is almost the same. It is a study of the policies, rules, and regulations of the courtrooms. When you lack the knowledge to complete your coursework assignments, never be afraid to seek assignment help online. I'm telling you not to be hesitant because there are still people who think twice or three times before hiring a professional writer to complete their homework.

It's great to have good storytelling. Since I started my freshman year of college, I have read your post and am anxious about the construction process. To solve the issue, I almost certainly will use an best assignment help birmingham, and I hope to do so correctly.


What’s up to every body, it’s my first pay a visit of this website; this website contains awesome and in fact excellent information in support of visitors. Thank you so much for sharing. sacred heart hospital school of nursing admission form
Users can connect with dApps (decentralised applications) on the Ethereum network and manage their Ethereum wallets using the browser extension MetaMask. It is readily downloaded and installed from the Chrome Web Store as a Metamask Chrome Extension. Once installed, users can use a seed phrase to create a new wallet or import an existing one. With MetaMask, users can use their browser to interact with decentralised applications, send and receive Ethereum and ERC-20 tokens, and view their account balances. Users can connect to numerous Ethereum networks, including the main Ethereum network, testnets, and private networks, and it offers increased security features including password protection. For anyone interested in using Ethereum and other blockchain technologies, MetaMask is a strong tool.
It is important to keep your Capital One Login information secure and to log out of your account when you are finished using it. If you suspect that your account has been compromised, you should contact Capital One immediately to report the issue and take steps to protect your account.
Your blogs are really good and interesting. It is very great and informative. 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 Bankruptcy lawyers in virginia. I got a lots of useful information in your blog. Keeps sharing more useful blogs..
It’s a very informative post to us, I have visited.hope you will share a quality blog. I mark this Post for future reference.
Silicon carbide and aluminium oxide are the major impregnating abrasive particles of sandpaper. sandpaper grit
thanks for your marvelous posting! I really enjoyed reading it, you happen to be a great author.
Your blogs are really good and interesting. It is very great and informative. Both Android and iPhone bury their "hey, am I connected to the Internet, and if so, how?" API facilities deep in their documentation bankruptcy lawyer chapter 7 near me. I got a lots of useful information in your blog. Keeps sharing more useful blogs..
PayPal Login

I find immense value in the depth and caliber of your blog. Your unwavering commitment to providing valuable information shines through each piece. Your blog serves as a dependable reservoir of wisdom and inspiration. Gratitude for consistently crafting such illuminating content.Driving Suspended License Misdemeanor New Jersey and Middlesex County Reckless Driving Attorney
"Of Zips and the Internet" offers a fascinating exploration into the interconnectedness of seemingly disparate concepts, weaving together the history of zippers with the evolution of the internet in a thought-provoking narrative. Through meticulous research and engaging storytelling, the author draws intriguing parallels between these two innovations, highlighting their transformative impact on society and culture. From the humble beginnings of the zipper's invention to the exponential growth of the internet age, this captivating journey invites readers to ponder the unexpected ways in which technology shapes our lives and reshapes our understanding of the world. With its insightful analysis and captivating anecdotes, "Of Zips and the Internet" is a compelling read that challenges conventional thinking and inspires curiosity about the hidden threads that connect our modern world.
Divorce Lawyers Fairfax VA
Fairfax Divorce Lawyer


"Of Zips and the Internet" offers an insightful exploration of digital evolution, blending technical history with engaging anecdotes. It's a fascinating read for anyone curious about the intersection of technology and society.
"Testamentos y Sucesiones de Abogados" ofrece servicios legales especializados en planificación testamentaria y gestión de sucesiones, brindando asesoramiento experto para garantizar una distribución justa y eficiente de los bienes. Con un enfoque centrado en la protección de los intereses del cliente y el cumplimiento de las disposiciones legales, son una opción confiable para resolver asuntos sucesorios con integridad y precisión.
testamentos y sucesiones de abogados

Post a Comment

Subscribe to Post Comments [Atom]

<< Home

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

Subscribe to Posts [Atom]