★ TouchArcade needs your help. Click here to support us on Patreon.

Connecting a Server to Download Content for Your App

10-29-2009, 02:16 PM
#1
Joined: Aug 2009
Location: California
Posts: 28
Connecting a Server to Download Content for Your App

This might be a total NOOB question, but I was wondering if anyone knew how to create a way to setup a server so people while playing your game can download new content (not necessarily in-game purchasable stuff) to be used. Kind of like how tap tap 2 does it (where you can download new songs)...

Was wondering technically how that works and if you guys have seen a tutorial on how to set that up. We're clueless right now so anything helps. Thanks!

Hug a Panda: New School Edutainment
Game in Dev: Q Racer - More You Know, Farther You Go

Stalk Us (Facebook) | Follow Us (Twitter) | Grock Us (Blog)
10-30-2009, 12:11 AM
#2
Here is some code slice from tyrian to download the data files from a URL.. It should give you some basic idea on how to do the client part...


Code:
 (void) downloadDataFiles{
	dlButton.alpha=0.0;
	progbar.alpha=0.9;
	// create the request
	NSURLRequest *theRequest;
	//NSLog(@" toggle value=%@", [[NSUserDefaults standardUserDefaults] stringForKey:@"useMirror"]);
	if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"useMirror"] boolValue]) 
		[[Reachability sharedReachability] setAddress:@"76.79.22.194"];
	else
		[[Reachability sharedReachability] setAddress:@"74.125.91.100"];
	if ([[Reachability sharedReachability] remoteHostStatus]==0) {
		UIAlertView *warninglert = [[UIAlertView alloc] initWithTitle:@"Warning: file is not accessible!" message:@"Please check internet connectivity and restart the application.\n You may also try to select using the mirror site in the Settings tab for the game." delegate: self cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[warninglert show];
		[warninglert release];
	}
	
	
	if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"useMirror"] boolValue]) {
		
		theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://camanis.net/tyrian/tyrian21.zip"]
									cachePolicy:NSURLRequestUseProtocolCachePolicy
								timeoutInterval:60.0];
	} else {
		
		theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://sites.google.com/a/camanis.net/opentyrian/tyrian/tyrian21.zip"]
									cachePolicy:NSURLRequestUseProtocolCachePolicy
								timeoutInterval:60.0];
		
	}
	
	// create the connection with the request
	// and start loading the data
	lbl.text=@"Attempting to get tyrian21.zip";
	[NSThread sleepForTimeInterval:0.5];
	NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
	//NSLog(@"Attempting to get tyrian21.zip");
	
	if (theConnection) {
		// Create the NSMutableData that will hold
		// the received data
		// receivedData is declared as a method instance elsewhere
		receivedData=[[NSMutableData data] retain];
		//NSLog(@"Starting download for tyrian21.zip");
	} else {
		NSLog(@"Could not DL data file...");
		lbl.text=@"Could not DL data file...";
		// inform the user that the download could not be made
	}
	
}



- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // append the new data to the receivedData
    // receivedData is declared as a method instance elsewhere
    [receivedData appendData:data];
	//NSLog(@"Got  some data of lenght %d for total of %d",[receivedData length],100*[receivedData length]/4754048) ;
	progbar.progress=(float)[receivedData length]/4754048;
	lbl.text=[NSString stringWithFormat:@"Downloading: %d %% done",100*[receivedData length]/4754048];
	
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // do something with the data
    // receivedData is declared as a method instance elsewhere
	
	//NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
	//NSString * rcPath = [[NSBundle mainBundle] resourcePath];
	lbl.text=@"Extracting the data files...";
	NSString *tmpPath =NSTemporaryDirectory();
	pathToZip = [tmpPath stringByAppendingString:@"tyrian21.zip"];
	NSArray *paths =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *destPath =[paths objectAtIndex:0];
	NSString *workingPath = [destPath stringByAppendingString:@"/tyrian21"];
	
	
	NSError * writeError;
	
	//[receivedData writeToFile: pathToZip atomically:NO];
	if (![receivedData writeToFile:pathToZip options: 0 error: &writeError])
	{
		NSLog(@"Error writing zip file: %@", [writeError localizedDescription]);
		lbl.text=@"Error extracting the data files";
	}
//	else
//	{
//		NSLog(@"Success writing %@",pathToZip);
//	}
	
	NSFileManager * FM=[NSFileManager defaultManager];
	
	/*
	 NSArray * dirContents = [FM directoryContentsAtPath: tmpPath];
	 for (int i=0; i<[dirContents count]; i++)
	 {
	 NSLog(@"DIR for Path %@: %@",tmpPath,[dirContents objectAtIndex:i]);
	 }
	 */
	
	ZipArchive * zipper =[[ZipArchive alloc] init];
	zipper.delegate = self;
	if(![zipper UnzipOpenFile:pathToZip])
	{
		NSLog(@"Error openning a zip file...");
		lbl.text=@"Error extracting the data files";
	}
	
	
	if (![zipper UnzipFileTo:destPath overWrite:YES])
	{
		NSLog(@"Error unzipping to %@",destPath);
		lbl.text=@"Error extracting the data files";
	}
	
	if (![zipper UnzipCloseFile])
	{
		NSLog(@"Error closing Zipped file");
		lbl.text=@"Error extracting the data files";
	}
	if (![FM removeItemAtPath: pathToZip error:&writeError])
	{
		NSLog(@"Failed to delete: %@",writeError);
	}
	
    // release the connection, and the data object
    [receivedData release];
	[zipper release];
	
		
	
	
	
	
	/* Set working directory to resource path */
	//[[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
	if (![[NSFileManager defaultManager] changeCurrentDirectoryPath:workingPath])
	{
		NSLog(@"Could not change path to: %@",workingPath);
	}
	lbl.text=@"Done. Please restart the game now!";
		
}

<< Check out our AppStore game titles: Tyrian, Super Methane Brothers, Cryptix, Powermanga, Rise Of The Triad >>
10-30-2009, 12:57 AM
#3
Joined: Aug 2009
Posts: 26
I can also recommend asihttprequest. It's a wrapper around the CFNetwork API, with a lot of (easy to use) options, like a-synchronous requests, gzip and authentication.

Lunarcy a really challenging retro looking arcade game.
10-30-2009, 01:28 AM
#4
Joined: Nov 2008
Location: Munich, Germany
Posts: 754
Send a message via Skype™ to mobile1up
Quote:
Originally Posted by Hug_a_Panda_Ben View Post
This might be a total NOOB question, but I was wondering if anyone knew how to create a way to setup a server so people while playing your game can download new content (not necessarily in-game purchasable stuff) to be used. Kind of like how tap tap 2 does it (where you can download new songs)...
i think all developers should have a website anyhow.

simply host the files on your website and make HTTP requests to download updates/data for your application. you can easily get a web hosting account and there is really not much difference between a normal web user and an iphone application when it comes to accessing information.

there are plenty of examples/libraries available to do HTTP access - combine it with some compression and you'll be all set. just make sure you have a web hosting aggreement that doesn't limit your content (bandwidth) - otherwise your app wont be able to download anything.

// Aaron Ardiri
Mobile 1UP is a proud indie developer - support us!
developer of Caveman / Caveman HD and GW Series
10-30-2009, 04:09 AM
#5
Joined: Aug 2009
Location: California
Posts: 28
Thanks a Lot

This is great info. Thanks for sharing your wisdom Gonna look into the stuff you guys posted. Thanks again!

Hug a Panda: New School Edutainment
Game in Dev: Q Racer - More You Know, Farther You Go

Stalk Us (Facebook) | Follow Us (Twitter) | Grock Us (Blog)