存档

文章标签 ‘iPhone’

iPhone开发之 - 缓存文件

2011年8月15日 没有评论

在iPhone应用程序中,我们经常要用去网络下载一些文件,比如 xml,图片等等!但是往往我们经常是需要反复读取这部分数据,或者我们要写一些文件在沙箱中,供下次打开程序的时候使用,这时候我们就需要用到缓存文件 (读写文件),今天和大家分享一个Demo,用来缓存从网上下载下来的图片和xml;

项目背景:
下载从网络下载图片,并写在temp目录下,temp目录下的文件在程序退出时会被清空,所以用来写本次要用的缓存内容很合适(我这么觉得)。
1、从一个url下载图片
NSURL *url = [NSURL URLWithString:@"http://*****.png"];

NSData *data = [NSData dataWithContentsOfURL:url];

UIImage *img = [UIImage imageWithData:data];

注:这是一种最普通最普通的图片下载方式,这种方式不太好,稍后我将和大家分享一下其他的下载方式

2、获取temp目录

-(NSString *)GetTempPath:(NSString*)filename{

NSString *tempPath = NSTemporaryDirectory();

return [tempPath stringByAppendingPathComponent:filename];

}

我们将要缓存的图片名传进去,得到完整的temp路径

3、将数据写入改路径

[data writeToFile:[self GetTempPath:@"test.png"] atomically:NO];

这里用到NSData的writeToFile方法,可以在API中找到更详细的解释

第一个参数:将数据写入的路径

第二个参数:是否覆盖原有文件YES为覆盖 NO则相反

方法返回一个BOOL类型的值,YES表示写入成功

4、判断路径下的文件是否已经存在

-(BOOL)isExistsFile:(NSString *)filepath{

NSFileManager *filemanage = [NSFileManager defaultManager];

return [filemanage fileExistsAtPath:filepath];

}

BOOL exist = [self isExistsFile:[self GetTempPath:@"test.png"]];

exist=YES表示文件已经存在

NO表示不存在

 

到这里,同类的问题都可以解决了吧。当然不仅仅是可以将图片保存到temp目录,其他的文件也行。当然也可以保存在document目录,这样我们可以长时间持有它。稍后将和大家分享document目录下的保存读取操作!

分类: iPhone 标签:

iphone开发之 - 常用方法(邮件,短信,电话,safari,拷贝)

2011年8月15日 没有评论

今天是事情比较多的一天了,差点没有时间写了,本着坚持每天写的原则,今天还是要写的,因为没有做太多准备,就把平时自己用到的一些常用的小功能拿出来和大家分享一下:

1、从程序内 发送短信
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:// "]];
短信的内容无法初始化,至少在3.2之前是这样,但是可以通过将要初始化的信息写到拷贝里来弥补。
2、从程序内 发送邮件
-(void) checkSender:(id) sender{

Class mailClass = (NSClassFromString(@”MFMailComposeViewController”));

if (mailClass != nil) {

if ([mailClass canSendMail]){

[self displayComposerSheet];

}else{

[self launchMailAppOnDevice];

}

} else{

[self launchMailAppOnDevice];

}

}

 

#pragma mark -

#pragma mark Compose Mail

 

// Displays an email composition interface inside the application. Populates all the Mail fields.

-(void)displayComposerSheet

{

MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];

picker.mailComposeDelegate = self;

[picker setSubject:@"subject"];

// Fill out the email body text

NSString *emailBody = @”email body”;

[picker setMessageBody:emailBody isHTML:NO];

[self presentModalViewController:picker animated:YES];

[picker release];

}

 

- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error

{

[self dismissModalViewControllerAnimated:YES];

}

 

3、从程序里 打开safari

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://tr4work.blog.163.com/"]];


4、从程序里 打开电话功能
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://1000000"]];

5、制作一个黏贴,拷贝
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];

pasteboard.string =@”初始化信息”;

分类: iPhone 标签:

iPhone中CGRect, CGPoint store in NSArray

2011年8月9日 1 条评论

CGPoint and other CG variable can store in NSArray by using NSValue class in iphone

To stor CGPoint in NSArray:
————————————

NSArray *points = [NSArray arrayWithObjects:
[NSValue valueWithCGPoint:CGPointMake(5.5, 8.3)],
[NSValue valueWithCGPoint:CGPointMake(11.9, 8.5)],
nil];

To retrieve CGPoint from array:
———————————–
From array to cgPoint variable.

NSValue *val = [points objectAtIndex:0];
CGPoint p = [val CGPointValue];

分类: iPhone 标签:

获取iPhone通讯录信息

2011年4月27日 没有评论

iPhone中联系人的信息是存放在系统数据库中的。数据库中的每一笔记录都是一个ABRecordRef实例。

通讯录主要存放两种记录:

1、联系人的信息:是ABPerson类型。主要包括联系人的姓名,电话号码,地址信息。

2、分组信息:是ABGroup类型。用于将联系人分到不同的组中。它只有一个属性,表示分组名称。

在viewDidLoad中添加下面代码,获取所有联系人和分组信息:

ABAddressBookRef addressBook =ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople (addressBook);
CFArrayRef allGroups = ABAddressBookCopyArrayOfAllGroups(addressBook);
for (id person in (NSArray *) allPeople)
[self logContact:person];
for (id group in (NSArray *) allGroups)
[self logGroup:group];
CFRelease(allGroups);
CFRelease(allPeople);
CFRelease(addressBook);

使用ABAddressBookCreate创建一个AddressBook实例。ABAddressBook CopyArrayOfAllPeople和ABAddressBook CopyArrayOfAllGroups查询出所有的联系人和分组信息。通过循环,使用logPerson和logGroup两个方法将信息输出到控制 台上。

logPerson方法:

CFStringRef name = ABRecordCopyCompositeName(person); ABRecordID recId = ABRecordGetRecordID(person); NSLog(@"Person Name: %@ RecordID:%d",name, recId);

logGroup方法:

CFStringRef name = ABRecordCopyValue(group,kABGroupNameProperty); ABRecordID recId = ABRecordGetRecordID(group); NSLog(@"Group Name: %@ RecordID:%d",name, recId);

总结:本文简单的讲述了如何通过sdk,将iphone的通讯录信息检索出来。

分类: iPhone 标签:

使用NSClassFromString

2010年8月27日 没有评论

NSClassFromString是一个很有用的东西,尤其在进行iPhone toolchain的开发上。

正常来说,
id myObj = [[NSClassFromString(@"MySpecialClass") alloc] init];

id myObj = [[MySpecialClass alloc] init];
是一样的。但是,如果你的程序中并不存在MySpecialClass这个类,下面的写法会出错,而上面的写法只是返回一个空对象而已。
因此,在某些情况下,可以使用NSClassFromString来进行你不确定的类的初始化。

比如在iPhone中,NSTask可能就会出现这种情况,所以在你需要使用NSTask时,最好使用:
[[NSClassFromString(@"NSTask") …..]]
而不要直接使用[NSTask …]这种写法。

NSClassFromString的好处是:
1 弱化连接,因此并不会把没有的Framework也link到程序中。
2 不需要使用import,因为类是动态加载的,只要存在就可以加载。因此如果你的toolchain中没有某个类的头文件定义,而你确信这个类是可以用 的,那么也可以用这种方法。

分类: iPhone 标签: ,

Iphone开发问题集[转]

2010年7月14日 没有评论

哎,好长时间没有怎么看书了,写的程序也少了点了,今天又过了写点东西的时候手又生疏了,好多都还有找,开这个blog写下我经常忘记的东西,呵呵,方便 以后查阅。

1.设置tag方便使用

在cell中放入多个控件的时候使用tag很方便的区分。在其他的地方使用tag也方便编程。呵呵

2.今天试验一个关于删除的问题,也就是直接在cell中添加一个按钮,点击按钮实现删除操作,这个应该是Apple不允许的,没有设置到编辑模式,我使 用的是直接reload数据源的方法,但是发现一个问题,也就是在选中该行的时候我想保存该行的行数,但是我保存不了,也不知道是为什么,难道是 delegate的缘故,还是第一次点该行再次点的时候呢个值已经变了,但是我看的时候是空,郁闷。最后我是用NSMutableArray来实现的,在 选中该行的时候我让NSMutableArray对象addObject该行然后在使用的时候取第一个值也就是NSMUtableArray ObjectAtIndex:0呵呵具体成果了。原理还在摸索中。

3.UITableViewCell的重用机制

UITableViewCell在加载的时候只更新内容,也就是说如果你在加载cell的时候在cell中加入button假如100个cell,你设置 tag的时候是更加row加入,你想的到得tag是从0到99,但是结果不是呢样的,如果你tableview能显示10个cell呢tag应该只有 10,在你向下拉的时候更改的仅仅是显示的内容。具体的重用机制还需要更深入研究。

4.NSArray初始化的时候,今天很晕,刚开始做的第一个程序我在初始化NSArray的时候居然这样搞了一下

NSArray *array = [[NSArray alloc]initWithObjects:(@”a”,@”b”,nil)];编译也没有错误,运行没结果,呵呵。去掉括号,没问题了。受C的影响。

5。向UINavigation添加tableView。

table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 440)];
[table setDelegate:self];
[table setDataSource:self];
[self.view addSubview:table];

6.得到Button的title

UIButton *but = [[UIbutton alloc] init];

[but setTitle:@"title" forState:UIControlStateNormal];

[but addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];

-(void)click:(id)sender

{

NSString *s = [sender titleForState:UIControlStateNormal];

}

7.对字符串的截取操作。按照“|”实现分割,去掉后面的数字只要前面部分

NSString *s = @”哈根达斯,4223|帝王蟹,3717|三文鱼,3255|提拉米苏,2733|生蚝,1860|烤鳗,1451|生鱼片,1430|龙虾色 拉,1252|北极贝,1230|鲍鱼片,772|芒果冰沙,730|烤鳗鱼,706|龙虾沙拉,692|海鲜泡饭,600|冰淇淋,508|芒果 汁,499|鲍片,357|佛跳墙,308|鲍鱼,295|HGDS,262 “;
NSMutableArray *array = [[s componentsSeparatedByString:@"|"]retain];
NSMutableArray *mutablearray = [[NSMutableArray alloc] init];
int i = 0;
for(i; i<[array count]; i++)
{
NSString *s1 = [array objectAtIndex:i];
NSArray *a = [s1 componentsSeparatedByString:@","];
[mutablearray addObject:[a objectAtIndex:0]];
}
for(i =0 ; i<[mutablearray count]; i++)
{
NSLog([NSString stringWithFormat:@"%@",[mutablearray objectAtIndex:i]]);
}

8.如何修改Xcode中Copyright 2009 __MyCompanyName__. All rights reserved.的名称。

以前在CC上见LV发过这个帖子,当时修改成功了,但是重装了一下系统,又挂了,显示的还是__MyCompanyName__,今天又被找到了,记下来 呵呵。

defaults write com.apple.xcode PBXCustomTemplateMacroDefinitions ‘{ ORGANIZATIONNAME = “名字”; }’
9.将音频转换成CAF格式

在mac上使用afconvert命令可以将音频文件转换成caf文件。

afconvert -f caff -d LEI16@44100 -c 1 in.wav out.caf

-f 指定文件格式

-d 数据格式,@44100指采样率

-c 通道数

10.怎样从core graphics获取UIImage

- (void)viewDidLoad
{
[super viewDidLoad];

UIGraphicsBeginImageContext(CGSizeMake(20,20));
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextBeginPath(ctx);
CGContextAddArc(ctx, 10, 10, 10, 0, 2*M_PI, 1);
CGContextSetRGBFillColor(ctx, 1,0, 0, 1);
CGContextFillPath(ctx);
UIImage *redBall = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *redBallView = [[UIImageView alloc] initWithImage:redBall];
redBallView.center = CGPointMake(160,330);
[self.view addSubview:redBallView];
}

11.UIImage imageNamed和UIImage imageWithContentsOfFile的区别

UIImage imageNamed将为这个图像提供缓存,所以如果你再次需要同一图像时,图像将被从内部缓存而
不是从资源中加载。而坏消息也是iPhone将为此图像提供缓存。这样如果图片过多就好出现内存泄露的现象。

UIImage imageWithContentsOfFile将不提供缓存。

12.在使用IB添加NAvigation的时候出现白屏。

刚开始的时候我把window给删掉了,结果出来就是白屏,没有东西,什么都没有,忘记还要关联App Delegate里面的window到window了。如果使用IB创建ViewController.xib是可以完全删除的。不影响运行结果。

13.- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath可以更改cell的高度,利用indexPath row可以随意更改每一行的高度例如

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

if([indexPath row] == 2)
return 80;
else {
return 100;
}
}

14.设置IPhone程序的启动画面

在XCode的项目的resource文件夹中追加名为Default.png的图片就可以了。你可以使用Organizer工 具来抓取iPhone实机上图片。

Organizer是XCode中内含的一个工具,通过选择菜单XCode -> Window -> Organizer来启动。这样就会在程序加载前的呢一会黑屏中运行该画面!

15.播放caf音频文件

引入AudioToolbox.framework。导入音频文件,声明变量SystemSoundID sound1;

NSString *path1 = [[NSBundle mainBundle] pathForResource:@”sound1″ ofType:@”caf”];获取音频文件路径
CFURLRef sound1URL = (CFURLRef)[NSURL fileURLWithPath:path1];将路径转换为CFURLRef
AudioServicesCreateSystemSoundID(sound1URL, &sound1);加载音频文件并与指定soundID联系起来

然后在需要播放的地方加入AudioServicesPlayAlertSound(sound1);就可以了。

16.将view设置成圆角

今天从CC上看到的,实验了一下,效果挺好的。呵呵

首先导入QuartzCore.framework,#import <QuartzCore/QuartzCore.h>

然后添加下面两行代码:

view.layer.cornerRadius = 8;//圆角
view.layer.masksToBounds = YES;//在所在的层绘制圆角

17.设置坐标和大小

CGPoint a = CGPointMake(10,20);
CGSize b = CGSizeMake(40,40);

CGRect aa = CGRectMake(10, 30, 240, 240);

18.把UIColor转换为CGColor

UIColor *redColor = [UIColor redColor];

CGColor *RedColor = redColor.CGColor;

19.CALayer就是层,这个层你随便控制他的大小,旋转,角度,坐标变化或者内容之类的信息,这些变化还可以通过动画表现出来。UIView所有你 能看到的显示的内容,后面都有一个Layer。下面来自定义添加一个CALayer。

CALayer *layer = [[CALayer alloc] init];//定义一个layer
CGRect aa = CGRectMake(10, 30, 240, 240);//设置该layer的坐标和大小
layer.frame = aa;
UIColor *c = [UIColor redColor];
[layer setBackgroundColor:(c.CGColor)];//设置该layer的背景,因为layer setBackgroundColor用到的是CGColor所以要进行一次转换
[self.view.layer insertSublayer:layer atIndex:0];//在self view中添加该layer

20.在使用Xcode编写程序的时候,在类方法上面option + 双击就可以跳到Document中的相关说明下面,很方便!

21.命令行解压tgz文件:

tar xzvf filename

22.从网络下载图片并显示,原以为很难,今天看到UIImage有imageWithData这个方法,试一下就出来了。

NSURL *url = [NSURL URLWithString:@"XXXX"];
NSData *picData = [NSData dataWithContentsOfURL:url];
UIImage *img = [UIImage imageWithData:picData];
[imageView setImage:img];

23.NSTimer传参数。

我们在使用NSTimer定时的时候有的时候需要传过去一个参数。我们可以这样来传参数。

首先定义NSTimer

NSTimer *timer;

timer = [NSTimer scheduledTimerWithTimeInterval:0.05f target:self selector:@selector(onTimer:) userInfo:parameter repeats:YES];

然后再onTimer事件中使用[time userInfo];就可以了。传什么类型在onTimer中使用对应类型就好了。

24.关于线程。在自己创建的子线程中不可以对控件进行操作。线程中需要使用NSAutoreleasePool。

[NSThread detachNewThreadSelector:@selector(threadMethod:) toTarget:self withObject:nil];

-(void)threadMethod:(NSString *)s{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

[self performSelectorOnMainThread:@selector(method:) withObject:nil waitUntilDone:YES];//这样就可以在主线程中进行控件的操作
[NSThread exit];
[pool release];
}

-(void)method{
………………
}

25.UIAlertView提示上面按钮触发的事件,根据选择的按钮触发不同的事件。

[alert addButtonWithTitle:@"YES"];
[alert addButtonWithTitle:@"NO"];

YES按钮返回的buttonIndex是0,NO按钮返回的buttonIndex是1这样就可以在下面的委托事件中使用了

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

26.更改cell选中后的颜色

cell.selectionStyle = UITableViewCellSelectionStyleGray;

27.使用IB添加tabbarcontroller后crash问题

用ib添加一个tabbarcontroller,里面放5个tabbaritems,关联5个xib文件。

Iphone开发问题集(不定时更新)
其中5个xib文件都是OK的。想着就ok了,结果运行的时候只要每一个view里面有controller操作,就会crash。实在是找不到原因,最 后请教高人,原来是IB弄错了。关联tabbaritems后还有关联相应的controller类。

在这里:

Iphone开发问题集(不定时更新)
其中class里面默认的是UIViewController,这里必须选择每一个view对应的controller类。

28.让label自适应里面的文字,自动调整宽度和高度。

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,0,0)];这个frame是初设的,没关系,后面还会重新设置其size。

[label setNumberOfLines:0];

NSString *s = @”string……”;

UIFont *font = [UIFont fontWithName:@"Arial" size:12];

CGSize size = CGSizeMake(320,2000);

CGSize labelsize = [s sizeWithFont:font constrainedToSize:size lineBreakMode:UILineBreakModeWordWrap];

[label setFrame:CGRectMake:(0,0, labelsize.width, labelsize.height)];

[self.view addSubView:label];

这样就可以对s赋值让其自动调整其大小了。其实宽度可以设置为固定,让其改高度更好。呵呵

29.在tableview中选种一行,当失去焦点的时候选 种行的颜色自动消失。

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

[table  deselectRowAtIndexPath:[table  indexPathForSelectedRow] animated:YES];

30。有用的色彩搭配表

http://www.print100.com/hk/html/csi.aspx

分类: iPhone 标签:

nsdata

2010年7月13日 没有评论

#import <Foundation/Foundation.h>
/**
NSData 对象是不可变的,它被创建后就不能改变。NSMutableData支持正数据内容中添加和删除字节
*/
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

const char *string=”hi there,this is a c string”;
//NSData 包装了大量的字节,可以获得数据的长度和指向字节起始位置的指针。
//如果将数据块传递给一个函数或方法,可以通过传递一个自动释放的NSData来实现,无需担心内存清除问题
//strlen(string)+1,它用于包含c字符串的尾部的零字节,通过包含零字节,可以使用%s格式的说明 符输出字符串
NSData *data=[NSData dataWithBytes:string length:strlen(string)+1];
NSLog(@”——%@”,data);

NSLog(@”length=%d,string=’%s’”,[data length],[data bytes]);
//atomically:设置为true或者yes,好像没有什么区别
[data writeToFile:@"/tmp/ss.txt" atomically:TRUE];

[pool drain];
return 0;
}

分类: iPhone 标签: ,

iPhone中的alert

2010年3月25日 没有评论

UIAlertView *alertstart;
alertstart = [[UIAlertView alloc] initWithTitle:@”Message” message:@”Congratulations!” delegate:self cancelButtonTitle:nil otherButtonTitles:@”Replay”,@”Exit”,nil];

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(buttonIndex == 0){
[self replayGame];   //开始游戏
}else if(buttonIndex == 1){
[self playExample]; //播放示例
}//end if
[alertView release];
}

分类: iPhone 标签: ,

iPhone 开发中如何合理使用内存

2010年3月23日 没有评论

iPhone 开发过程中,内存的使用至关重要。不但要合理分配使用内存,还要注意内存泄露的问题, 因为内存泄露会导致程序由于内存不足而崩溃。根据个人开发的经验来看,在开发iPhone程序的过程中,关于内存的问题需要注意以下几点:

内存分配、释放成对出现

使用 alloc 分配的内存对象需要在用完后 调用release释放

注意copy,retain,assign操作符的区别

copy, retain操作符赋值的对象和alloc一样,需要release释放,否则会导致内存泄露

assign 操作符的含义是将对象指向另一对象, 两者指向的是同一内存对象,无需调用release释放

NSArray, NSDictionary, NSMutableArray, NSMutableDictionary等容器类, 在使用这些容器类的时候要注意, 在添加对象到这些类对象时,容器类会自动调用一次retain,比如

NSString* string = [[NSString alloc] initWithString:@”test string”]; // refCount = 1

NSArray* array = [NSArray array];

[array addObject:string]; // refCount = 2

[string release]; // refCount = 1

这种情况, 即便string已经调用release,但是在加入 array中时已经调用了一次retain,注意refCount的变化

简单介绍一下iPhone 或者说Objective C对对象的管理机制。 OC中采用一种引用计数refCount的方式来管理内存对象,当refCount等于0的时候就会释放对象所占的内存, 操作符alloc,copy, retain都会将refCount加1表示引用计数增加, 而调用release使 refCount自动减1,当refCount=0时表示该对象已经没有被引用,可以将其释放, 之后该对象便不可用

连续重复分配内存的过程最好创建自己的自动释放池 NSAutoreleasePool,通常是在for、while等循环操作过程中,比如

for( int i=0; i < 100; i++ )

{

NSString* str = [[NSString alloc] initWithString:@”some string”];

// 针对str的操作

[str release];

}

在这种情况下,有2点需要注意,首先如果可能,就把str的分配、释放放在for循环外面, 从而减少内存的分配、释放导致程序效率低下,也利于内存回收,如上例应该为

NSString* str = [[NSString alloc] initWithString:@”some string”];

分类: iPhone 标签:

Objective-C中切分数组

2010年3月23日 没有评论

在很多脚本语言如ruby,python中都有将字符串切分成数组或者将数组元素以某个间隔字符串间隔形成新的数组。 其实NSArray也提供了这样的功能。

使用-componentsSeparatedByString:来切分NSArray。 如:
NSString *string = @”white:black:blue:red”;
NSArray *aArray = [string componentsSeparatedByString:@":"];

用-componentsJoinedByString:来合并NSArray中的各个元素并创建一个新的字符串,如:
string = [aArray componentsJoinedByString:@","];

这样,上面的数组就中的各个元素就以”,”分割形成一个字符串。

分类: iPhone 标签: , ,