What’d you do to my phone bill?!
If your game is going to send data over the network, remember that it’s going to cost your users money to do that. If it costs too much – i.e. if they raise an eyebrow even a bit at the cost – you’re in trouble. To avoid this, you’ve got to compress any data sent over the network. The second place where uncompressed data can screw up your app is in the game. Uncompressed text data stored in the game can slow load times and compromise the user’s experience. Large amounts of text data in-game need to be compressed and doing so can speed up your load times, which is always a plus. Copy and add these two files to your project to get around these two landmines:
Posts Tagged ‘data’
Compression
Posted in Code, tagged compression, data, iPhone on May 6, 2009 | Leave a Comment »
1. Xcode -> Project -> Edit Project Settings -> Linking -> Other Linker Flags -> -lz (be sure to do it for all configurations)
2. follow the usage in the main.m file below
//
// Compress.h
//
@interface Compress : NSObject {
}
// Returns a data object containing a Zlib compressed copy of the receivers
// contents.
+ (NSData *)compress:(NSData *)data;
// Returns a data object containing a Zlib decompressed copy of the receivers
// contents.
+ (NSData *)decompress:(NSData *)data;
@end
//
// Compress.m
//
#import “Compress.h”
#import “zlib.h”
@implementation Compress
// 16K chunks for expansion
const int CHUNK_LENGTH = 16384;
+ (NSData *)compress:(NSData *)data {
if ([data length] == 0) {
return data;
}
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in = (Bytef *)[data bytes];
strm.avail_in = [data length];
// Compresssion Levels:
// Z_NO_COMPRESSION
// Z_BEST_SPEED
// Z_BEST_COMPRESSION
// Z_DEFAULT_COMPRESSION
if (deflateInit(&strm, Z_DEFAULT_COMPRESSION) != Z_OK) {
return nil;
}
NSMutableData *compressed = [NSMutableData dataWithLength:CHUNK_LENGTH];
do {
if (strm.total_out >= [compressed length]) {
[compressed increaseLengthBy:CHUNK_LENGTH];
}
strm.next_out = [compressed mutableBytes] + strm.total_out;
strm.avail_out = [compressed length] – strm.total_out;
deflate(&strm, Z_FINISH);
} while (strm.avail_out == 0);
deflateEnd(&strm);
[compressed setLength:strm.total_out];
return [NSData dataWithData:compressed];
}
+ (NSData *)decompress:(NSData *)data {
if ([data length] == 0) {
return data;
}
unsigned full_length = [data length];
unsigned half_length = [data length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength:full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[data bytes];
strm.avail_in = [data length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit(&strm) != Z_OK) {
return nil;
}
while (!done) {
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length]) {
[decompressed increaseLengthBy:half_length];
}
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] – strm.total_out;
// Inflate another chunk.
status = inflate(&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END) {
done = YES;
} else if (status != Z_OK) {
break;
}
}
if (inflateEnd(&strm) != Z_OK) {
return nil;
}
// Set real length.
if (done) {
[decompressed setLength:strm.total_out];
return [NSData dataWithData:decompressed];
} else {
return nil;
}
}
@end
//
// main.m
//
#import <Foundation/Foundation.h>
#import “Compress.h”
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *string = @”This is a test of the compression library. Usually text compresses better than binary data. Don’t forget to add ‘-lz’ to ‘Other Linker Flags’ in your project settings!”;
NSData *data = [string dataUsingEncoding:[NSString defaultCStringEncoding]];
NSData *compressedData = [Compress compress:data];
printf(“compressed bytes: %d\n”, [compressedData length]);
NSData *decompressedData = [Compress decompress:compressedData];
printf(“decompressed bytes: %d\n”, [decompressedData length]);
NSString *decompressedString = [[NSString alloc] initWithData:decompressedData encoding:[NSString defaultCStringEncoding]];
NSLog(decompressedString);
[decompressedString release];
[pool release];
return 0;
}