Posts Tagged ‘Objective-C’
iPhone开发中的问题整理(一)
看到很刚开始开发iPhone软件的朋友问很多问题,其实同样的问题我也碰到过, 所以抽时间把能想到的或者碰到的问题汇总一下, 一来可以给自己做个备忘也可以和朋友们分享探讨。
1. iPhone SDK 开发能不能使用C / C++ 语言?
Answer: iPhone SDK的开发的基础框架是基于cocoa库的, Objective-C 是cocoa的开发语言, 但基于Objective-C的特性,在iPhone程序中可以使用C/C++进行功能开发以及使用第三方C/C++库。 Read the rest of this entry »
ZipArchive has been updated to version 1.1 (更新至1.1版)
ZipArchive is a wrapper class to compress and uncompress zip files for Objective-C and cocoa use. It’s developed based on minizip and zlib. The latest version is 1.1, new feature includes :
✩ create password protected zip files
✩ unzip password protected zip files
To obtain the new version up to date, please visit the project website http://code.google.com/p/ziparchive/
ZipArchive 是基于minizip和zlib的Objective-C 类, 用于创建和解压zip格式的压缩文件, 最新版本为1.1, 新增功能如下:
✩ 创建有密码保护的zip文件
✩ 解压有密码保护的zip文件
为了保证获取最新的版本, 请访问该项目网页 http://code.google.com/p/ziparchive/
Create custom checkbox style button for iPhone
Recently, I got a task to develop an application for iPhone. In the application, there are some optional choices for user to decide further processes. The first idea jumps out from my head is something like button with a checkbox just the same as other desktop platforms, but unfortunately, iPhone SDK doesn’t provide such view. The only official choice is the ON|OFF switch view, but it really can’t represent the actually meaning of the options. So comes out the idea of writing custom checkbox style button.
It’s really easy to implement. What we need is two images which are statuses for check and uncheck. Here are the runtime screenshots:

The class for Checkbox button is CheckButton, it’s inherited from UIButton, look at the declaration:
1 2 3 4 5 6 7 8 9 10 | #import @interface CheckButton : UIButton { BOOL _checked; } @property (nonatomic, setter=setChecked) BOOL checked; -(void) setChecked:(BOOL) check; @end |
Implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #import "CheckButton.h"
@implementation CheckButton
@synthesize checked = _checked;
-(id) init
{
if( self=[super init] )
{
self.checked = NO;
[self addTarget:self action:@selector(OnCheck:) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
-(void) awakeFromNib
{
self.checked = NO;
[self addTarget:self action:@selector(OnCheck:) forControlEvents:UIControlEventTouchUpInside];
}
-(void) dealloc
{
[super dealloc];
}
-(void) setChecked:(BOOL) check
{
_checked = check;
if( _checked )
{
UIImage* img = [UIImage imageNamed:@"check.png"];
[self setImage:img forState:UIControlStateNormal];
}
else
{
UIImage* img = [UIImage imageNamed:@"uncheck.png"];
[self setImage:img forState:UIControlStateNormal];
}
}
-(void) OnCheck:(id) sender
{
self.checked = !_checked;
}
@end |
To use the class, import the header where contains the button, and declare a IBOutlet with type of “CheckButton”, and connect the IBOutlet in InterfaceBuilder to the member as shown below:

This is simple but exactly meet my requirement. Of course, someone wants to include title text of the button within the button class, it’s sure to be easy to do
base64 encoder/decoder for objective-c 编码及解码
base64是广为使用的一种编码及解码方式, 通常用于网络传输和邮件传输中,使用base64可以将标点符号以及多字节文字等特殊字符编码以便传输,以下是base64 编码解码的objective-c代码, 可以用于desktop和iphone程序当中
头文件
1 2 3 4 5 6 7 | #include <UIKit/UIKit.h> extern size_t EstimateBas64EncodedDataSize(size_t inDataSize); extern size_t EstimateBas64DecodedDataSize(size_t inDataSize); extern bool Base64EncodeData(const void *inInputData, size_t inInputDataSize, char *outOutputData, size_t *ioOutputDataSize, BOOL wrapped); extern bool Base64DecodeData(const void *inInputData, size_t inInputDataSize, void *ioOutputData, size_t *ioOutputDataSize); |
实现文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | #include "Base64Transcoder.h" #include <math.h> const UInt8 kBase64EncodeTable[64] = { /* 0 */ 'A', /* 1 */ 'B', /* 2 */ 'C', /* 3 */ 'D', /* 4 */ 'E', /* 5 */ 'F', /* 6 */ 'G', /* 7 */ 'H', /* 8 */ 'I', /* 9 */ 'J', /* 10 */ 'K', /* 11 */ 'L', /* 12 */ 'M', /* 13 */ 'N', /* 14 */ 'O', /* 15 */ 'P', /* 16 */ 'Q', /* 17 */ 'R', /* 18 */ 'S', /* 19 */ 'T', /* 20 */ 'U', /* 21 */ 'V', /* 22 */ 'W', /* 23 */ 'X', /* 24 */ 'Y', /* 25 */ 'Z', /* 26 */ 'a', /* 27 */ 'b', /* 28 */ 'c', /* 29 */ 'd', /* 30 */ 'e', /* 31 */ 'f', /* 32 */ 'g', /* 33 */ 'h', /* 34 */ 'i', /* 35 */ 'j', /* 36 */ 'k', /* 37 */ 'l', /* 38 */ 'm', /* 39 */ 'n', /* 40 */ 'o', /* 41 */ 'p', /* 42 */ 'q', /* 43 */ 'r', /* 44 */ 's', /* 45 */ 't', /* 46 */ 'u', /* 47 */ 'v', /* 48 */ 'w', /* 49 */ 'x', /* 50 */ 'y', /* 51 */ 'z', /* 52 */ '0', /* 53 */ '1', /* 54 */ '2', /* 55 */ '3', /* 56 */ '4', /* 57 */ '5', /* 58 */ '6', /* 59 */ '7', /* 60 */ '8', /* 61 */ '9', /* 62 */ '+', /* 63 */ '/' }; /* -1 = Base64 end of data marker. -2 = White space (tabs, cr, lf, space) -3 = Noise (all non whitespace, non-base64 characters) -4 = Dangerous noise -5 = Illegal noise (null byte) */ const SInt8 kBase64DecodeTable[128] = { /* 0x00 */ -5, /* 0x01 */ -3, /* 0x02 */ -3, /* 0x03 */ -3, /* 0x04 */ -3, /* 0x05 */ -3, /* 0x06 */ -3, /* 0x07 */ -3, /* 0x08 */ -3, /* 0x09 */ -2, /* 0x0a */ -2, /* 0x0b */ -2, /* 0x0c */ -2, /* 0x0d */ -2, /* 0x0e */ -3, /* 0x0f */ -3, /* 0x10 */ -3, /* 0x11 */ -3, /* 0x12 */ -3, /* 0x13 */ -3, /* 0x14 */ -3, /* 0x15 */ -3, /* 0x16 */ -3, /* 0x17 */ -3, /* 0x18 */ -3, /* 0x19 */ -3, /* 0x1a */ -3, /* 0x1b */ -3, /* 0x1c */ -3, /* 0x1d */ -3, /* 0x1e */ -3, /* 0x1f */ -3, /* ' ' */ -2, /* '!' */ -3, /* '"' */ -3, /* '#' */ -3, /* '$' */ -3, /* '%' */ -3, /* '&' */ -3, /* ''' */ -3, /* '(' */ -3, /* ')' */ -3, /* '*' */ -3, /* '+' */ 62, /* ',' */ -3, /* '-' */ -3, /* '.' */ -3, /* '/' */ 63, /* '0' */ 52, /* '1' */ 53, /* '2' */ 54, /* '3' */ 55, /* '4' */ 56, /* '5' */ 57, /* '6' */ 58, /* '7' */ 59, /* '8' */ 60, /* '9' */ 61, /* ':' */ -3, /* ';' */ -3, /* '<' */ -3, /* '=' */ -1, /* '>' */ -3, /* '?' */ -3, /* '@' */ -3, /* 'A' */ 0, /* 'B' */ 1, /* 'C' */ 2, /* 'D' */ 3, /* 'E' */ 4, /* 'F' */ 5, /* 'G' */ 6, /* 'H' */ 7, /* 'I' */ 8, /* 'J' */ 9, /* 'K' */ 10, /* 'L' */ 11, /* 'M' */ 12, /* 'N' */ 13, /* 'O' */ 14, /* 'P' */ 15, /* 'Q' */ 16, /* 'R' */ 17, /* 'S' */ 18, /* 'T' */ 19, /* 'U' */ 20, /* 'V' */ 21, /* 'W' */ 22, /* 'X' */ 23, /* 'Y' */ 24, /* 'Z' */ 25, /* '[' */ -3, /* '\' */ -3, /* ']' */ -3, /* '^' */ -3, /* '_' */ -3, /* '`' */ -3, /* 'a' */ 26, /* 'b' */ 27, /* 'c' */ 28, /* 'd' */ 29, /* 'e' */ 30, /* 'f' */ 31, /* 'g' */ 32, /* 'h' */ 33, /* 'i' */ 34, /* 'j' */ 35, /* 'k' */ 36, /* 'l' */ 37, /* 'm' */ 38, /* 'n' */ 39, /* 'o' */ 40, /* 'p' */ 41, /* 'q' */ 42, /* 'r' */ 43, /* 's' */ 44, /* 't' */ 45, /* 'u' */ 46, /* 'v' */ 47, /* 'w' */ 48, /* 'x' */ 49, /* 'y' */ 50, /* 'z' */ 51, /* '{' */ -3, /* '|' */ -3, /* '}' */ -3, /* '~' */ -3, /* 0x7f */ -3 }; const UInt8 kBits_00000011 = 0x03; const UInt8 kBits_00001111 = 0x0F; const UInt8 kBits_00110000 = 0x30; const UInt8 kBits_00111100 = 0x3C; const UInt8 kBits_00111111 = 0x3F; const UInt8 kBits_11000000 = 0xC0; const UInt8 kBits_11110000 = 0xF0; const UInt8 kBits_11111100 = 0xFC; size_t EstimateBas64EncodedDataSize(size_t inDataSize) { size_t theEncodedDataSize = (int)ceil(inDataSize / 3.0) * 4; theEncodedDataSize = theEncodedDataSize / 72 * 74 + theEncodedDataSize % 72; return(theEncodedDataSize); } size_t EstimateBas64DecodedDataSize(size_t inDataSize) { size_t theDecodedDataSize = (int)ceil(inDataSize / 4.0) * 3; //theDecodedDataSize = theDecodedDataSize / 72 * 74 + theDecodedDataSize % 72; return(theDecodedDataSize); } bool Base64EncodeData(const void *inInputData, size_t inInputDataSize, char *outOutputData, size_t *ioOutputDataSize, BOOL wrapped) { size_t theEncodedDataSize = EstimateBas64EncodedDataSize(inInputDataSize); if (*ioOutputDataSize < theEncodedDataSize) return(false); *ioOutputDataSize = theEncodedDataSize; const UInt8 *theInPtr = (const UInt8 *)inInputData; UInt32 theInIndex = 0, theOutIndex = 0; for (; theInIndex < (inInputDataSize / 3) * 3; theInIndex += 3) { outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_11111100) >> 2]; outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_00000011) << 4 | (theInPtr[theInIndex + 1] & kBits_11110000) >> 4]; outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex + 1] & kBits_00001111) << 2 | (theInPtr[theInIndex + 2] & kBits_11000000) >> 6]; outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex + 2] & kBits_00111111) >> 0]; if (wrapped && (theOutIndex % 74 == 72)) { outOutputData[theOutIndex++] = '\r'; outOutputData[theOutIndex++] = '\n'; } } const size_t theRemainingBytes = inInputDataSize - theInIndex; if (theRemainingBytes == 1) { outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_11111100) >> 2]; outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_00000011) << 4 | (0 & kBits_11110000) >> 4]; outOutputData[theOutIndex++] = '='; outOutputData[theOutIndex++] = '='; if (wrapped && (theOutIndex % 74 == 72)) { outOutputData[theOutIndex++] = '\r'; outOutputData[theOutIndex++] = '\n'; } } else if (theRemainingBytes == 2) { outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_11111100) >> 2]; outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_00000011) << 4 | (theInPtr[theInIndex + 1] & kBits_11110000) >> 4]; outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex + 1] & kBits_00001111) << 2 | (0 & kBits_11000000) >> 6]; outOutputData[theOutIndex++] = '='; if (wrapped && (theOutIndex % 74 == 72)) { outOutputData[theOutIndex++] = '\r'; outOutputData[theOutIndex++] = '\n'; } } return(true); } bool Base64DecodeData(const void *inInputData, size_t inInputDataSize, void *ioOutputData, size_t *ioOutputDataSize) { memset(ioOutputData, '.', *ioOutputDataSize); size_t theDecodedDataSize = EstimateBas64DecodedDataSize(inInputDataSize); if (*ioOutputDataSize < theDecodedDataSize) return(false); *ioOutputDataSize = 0; const UInt8 *theInPtr = (const UInt8 *)inInputData; UInt8 *theOutPtr = (UInt8 *)ioOutputData; size_t theInIndex = 0, theOutIndex = 0; UInt8 theOutputOctet; size_t theSequence = 0; for (; theInIndex < inInputDataSize; ) { SInt8 theSextet = 0; SInt8 theCurrentInputOctet = theInPtr[theInIndex]; theSextet = kBase64DecodeTable[theCurrentInputOctet]; if (theSextet == -1) break; while (theSextet == -2) { theCurrentInputOctet = theInPtr[++theInIndex]; theSextet = kBase64DecodeTable[theCurrentInputOctet]; } while (theSextet == -3) { theCurrentInputOctet = theInPtr[++theInIndex]; theSextet = kBase64DecodeTable[theCurrentInputOctet]; } if (theSequence == 0) { theOutputOctet = (theSextet >= 0 ? theSextet : 0) << 2 & kBits_11111100; } else if (theSequence == 1) { theOutputOctet |= (theSextet >- 0 ? theSextet : 0) >> 4 & kBits_00000011; theOutPtr[theOutIndex++] = theOutputOctet; } else if (theSequence == 2) { theOutputOctet = (theSextet >= 0 ? theSextet : 0) << 4 & kBits_11110000; } else if (theSequence == 3) { theOutputOctet |= (theSextet >= 0 ? theSextet : 0) >> 2 & kBits_00001111; theOutPtr[theOutIndex++] = theOutputOctet; } else if (theSequence == 4) { theOutputOctet = (theSextet >= 0 ? theSextet : 0) << 6 & kBits_11000000; } else if (theSequence == 5) { theOutputOctet |= (theSextet >= 0 ? theSextet : 0) >> 0 & kBits_00111111; theOutPtr[theOutIndex++] = theOutputOctet; } theSequence = (theSequence + 1) % 6; if (theSequence != 2 && theSequence != 4) theInIndex++; } *ioOutputDataSize = theOutIndex; return(true); } |
在自己的程序中实现Email功能
在iPhone上如果想在应用程序里发送邮件只能通过调用系统默认email客户端程序,使用mailto协议,具体方法为
1 | [[UIApplication sharedApplication] OpenURL:@"mailto:someone@web.com?subject=test email...">mailto:someone@web.com?subject=test email..."]; |
这种方式建档方便, 如果只是简单的发送文本完全可以胜任, 不过如果需要发送附件或者html格式化的信件,这种方法将无法实现,此时需要在自己的程序中实现email发送代码。 如果你不想自己去实现发送的代码,请看SKPSMTPMessage , 该项目是google上的开源项目,实现了iPhone平台通过SMTP发送email的功能, 你可以通过http://code.google.com/p/skpsmtpmessage 获得代码,加入自己的项目即可。
SKPSMTPMessage 的使用方法也很简单,只需要分配一个新的SKPSMTPMessage 对象,设置相应的字段即可,比如
1 2 3 4 5 6 7 8 9 10 | SKPSMTPMessage mailMsg = [[SKPSMTPMessage alloc] init]; mailMsg.fromEmail = @"mylogin@gmail.com"; mailMsg.toEmail = @"mylogin@gmail.com"; mailMsg.relayHost = @"smtp.gmail.com"; mailMsg.requiresAuth = YES; mailMsg.login = @"mylogin"; mailMsg.pass = @"mypassword"; mailMsg.subject = @"test message"; mailMsg.validateSSLChain = NO; // 只用于自验证 mailMsg.delegate = self; |
iPhone开发之打包zip文件
程序需要往服务器上上传文件, 因为iPhone用户往往是用gprs或者edge网络,为了节约流量以及加快上传速度,所以只好将要上传的文件打包成zip文件,这样体积小了, 也为用户节约了时间和金钱。 开始的时候抱有意思希望去挖掘SDK文档, 未果, sdk不提供zip相关接口,在apple论坛打听了一下,很多dx给的建议是用apple script在后台打包, 对此领域不熟悉,放弃。 好在iPhone的官方SDK支持zLib库,这就好了, 找来minizip,一个封装的挺好的C/C++ zip库, 动手创建Objective-C对象封装之, 只需要几行代码即可完成, 简单实用。
使用方法如下
1 2 3 4 5 6 7 | BOOL ret = [zip CreateZipFile2:l_zipfile]; ret = [zip addFileToZip:l_photo newname:@"photo.jpg"]; if( ![zip CloseZipFile2] ) { l_zipfile = @""; } [zip release]; |
其中 l_photo是之源文件路径, @”photo.jpg” 是在新的文件名(不带路径)
之前没有实现 解压缩的代码, 今天补上了, 使用起来也和压缩差不多,下面时用法演示
1 2 3 4 5 6 7 8 9 10 11 | ZipArchive* za = [[ZipArchive alloc] init]; if( [za UnzipOpenFile:@"/Volumes/data/testfolder/Archive.zip"] ) { BOOL ret = [za UnzipFileTo:@"/Volumes/data/testfolder/extract" overWrite:YES]; if( NO==ret ) { } [za UnzipCloseFile]; } [za release]; |
代码在附件中