1
获取系统语言设置
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSArray *languages = [userDefault objectForKey:@
"AppleLanguages"
];
NSString *preferredLang = [languages objectAtIndex:
0
];
2
缓存路径下文件大小
- (unsigned
long
long
int
) cacheFolderSize
{
NSFileManager *_manager = [NSFileManager defaultManager];
NSArray *_cachePaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
NSString *_cacheDirectory = [_cachePaths objectAtIndex:];
NSArray *_cacheFileList;
NSEnumerator *_cacheEnumerator;
NSString *_cacheFilePath;
unsigned
long
long
int
_cacheFolderSize = ;
_cacheFileList = [ _manager subpathsAtPath:_cacheDirectory];
_cacheEnumerator = [_cacheFileList objectEnumerator];
while
(_cacheFilePath = [_cacheEnumerator nextObject])
{
NSDictionary *_cacheFileAttributes = [_managerfileAttributesAtPath:
[_cacheDirectory stringByAppendingPathComponent:_cacheFilePath]
traverseLink:YES];
_cacheFolderSize += [_cacheFileAttributes fileSize];
}
return
_cacheFolderSize;
}
3Popover push 时 Frame无法改变解决办法
在popover中的ViewController中实现:
- (
void
)viewWillAppear:(BOOL)animated
{
CGSize size = CGSizeMake(
320
,
480
);
self.contentSizeForViewInPopover = size;
[
super
viewWillAppear:animated];
}
4tableview滑动导致NSTimer和委托回调停止解决办法
/ /请求回调
NSURLRequest * 请求 = ...
scheduleInRunLoop :[ NSRunLoop currentRunLoop ]
forMode :NSRunLoopCommonModes ]
[ 连接开始] / /定时器回调
NSTimer * updateTimer = [NSTimer scheduledTimerWithTimeInterval:
0
.01f目标:自我选择:选择(updatePencent)的UserInfo:无重复:是];
* NSRunLoop主要= [NSRunLoop currentRunLoop]
[主要addTimer:updateTimer forMode:NSRunLoopCommonModes];
5
手势识别类
UIGestureRecognizer
6SFHFKeychainUtils 存储信息
苹果SDK自带的就有密码保护,使用方法很简单,如下:
1
、引入Security.frameWork框架。
2
、引入头文件:SFHKeychainUtils.h.
3
、存密码:
[SFHFKeychainUtils storeUsername:@
"dd"
andPassword:@
"aa"
forServiceName:SERVICE_NAMEupdateExisting:
1
error:nil];
[SFHFKeychainUtils deleteItemForUsername:@
"dd"
andServiceName:SERVICE_NAME error:nil];
4
、取密码:
NSString *passWord = [SFHFKeychainUtils getPasswordForUsername:@
"dd"
andServiceName:SERVICE_NAMEerror:nil];
7missing required architecture i386 in file 解决办法
在TargetInfo里面修改 Framework Search Pasths 删除里面内容就可以了。
8view 放大缩小动画效果
myWeiBoImageVC = [[UIViewController alloc] init];
myWeiBoImageVC.view.clipsToBounds = YES;
myWeiBoImageVC.view.alpha =
0.0
;
myWeiBoImageVC.view.frame = CGRectMake(
64
,
0
,
1024
-
64
,
768
-
20
);
[self.view addSubview:myWeiBoImageVC.view];
CGAffineTransform newTransform =
CGAffineTransformScale(myWeiBoImageVC.view.transform,
0.1
,
0.1
);
[myWeiBoImageVC.view setTransform:newTransform];
myWeiBoImageVC.view.center = CGPointMake(
670
,
100
);
[self performSelector:
@selector
(imageViewControllerBigAnimation)];
- (
void
)imageViewControllerBigAnimation{
[UIView beginAnimations:@
"imageViewBig"
context:nil];
[UIView setAnimationDuration:
0.5
];
CGAffineTransform newTransform = CGAffineTransformConcat(myWeiBoImageVC.view.transform, CGAffineTransformInvert(myWeiBoImageVC.view.transform));
[myWeiBoImageVC.view setTransform:newTransform];
myWeiBoImageVC.view.alpha =
1.0
;
myWeiBoImageVC.view.center = CGPointMake(
416
,
510
);
[UIView commitAnimations];
}
- (
void
)imageViewControllerSmallAnimation{
[UIView beginAnimations:@
"imageViewSmall"
context:nil];
[UIView setAnimationDuration:
0.5
];
CGAffineTransform newTransform = CGAffineTransformScale(myWeiBoImageVC.view.transform,
0.1
,
0.1
);
[myWeiBoImageVC.view setTransform:newTransform];
myWeiBoImageVC.view.center = CGPointMake(
670
,
100
);
[UIView commitAnimations];
}
9UIScrollView 控制View缩放
allImageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(
0
,
0
,
768
,
1024
)];
allImageScrollView.minimumZoomScale =
0.3
;
allImageScrollView.maximumZoomScale =
1.0
;
allImageScrollView.backgroundColor = [UIColor clearColor];
allImageScrollView.delegate = self;
[self.view addSubview:allImageScrollView];
mPicStatusesViewController = [[PicStatusesViewController alloc] init];
[allImageScrollView addSubview:mPicStatusesViewController.view];
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return
mPicStatusesViewController.view;
}
- (
void
)scrollViewDidZoom:(UIScrollView *)scrollView
{
}
- (
void
)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(
float
)scale
{
}
10
、iOS3.
2
播放视频
NSString *urlString = [NSString stringWithString:@
"视频url"
];
NSURL *movieUrl = [[NSURL alloc] initWithString:urlString];
MPMoviePlayerController *myMoviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieUrl];
myMoviePlayer.view.frame = CGRectMake(
250
,
250
,
350
,
350
);
[self.view addSubview:myMoviePlayer.view];
myMoviePlayer.shouldAutoplay = YES;
myMoviePlayer.scalingMode= MPMovieScalingModeAspectFit;
[myMoviePlayer play];
11
、谷歌地图翻起动画效果
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setDuration:
0.35
];
[animation setTimingFunction:UIViewAnimationCurveEaseInOut];
if
(!curled){
animation.type = @
"pageCurl"
;
animation.fillMode = kCAFillModeForwards;
animation.endProgress =
0.40
;
}
else
{
animation.type = @
"pageUnCurl"
;
animation.fillMode = kCAFillModeBackwards;
animation.startProgress =
0.30
;
}
[animation setRemovedOnCompletion:NO];
[self.view exchangeSubviewAtIndex:
0
withSubviewAtIndex:
1
];
[self.view.layer addAnimation:animation forKey:@
"pageCurlAnimation"
];
12
、给View添加阴影 和边框
UIImageView *imgvPhoto = [UIImageView alloc] init];
CALayer *layer = [_imgvPhoto layer];
layer.borderColor = [[UIColor whiteColor] CGColor];
layer.borderWidth =
5
.0f;
_imgvPhoto.layer.shadowColor = [UIColor blackColor].CGColor;
_imgvPhoto.layer.shadowOffset = CGSizeMake(
0
,
0
);
_imgvPhoto.layer.shadowOpacity =
0.5
;
_imgvPhoto.layer.shadowRadius =
10.0
;
_imgvPhoto.layer.shadowColor = [UIColor blackColor].CGColor;
_imgvPhoto.layer.shadowOffset = CGSizeMake(
4
,
4
);
_imgvPhoto.layer.shadowOpacity =
0.5
;
_imgvPhoto.layer.shadowRadius =
2.0
;
13
、使用NSTimer与UIView动画实现飘雪效果
viewDidLoad事件中,增加一个图片及定时器并启动,这里的pic请在头文件中定义。
-(
void
)viewDidLoad{
[
super
viewDidLoad];
self.pic = [UIImage imageNamed:@
"snow.png"
];
[NSTimer scheduledTimerWithTimeInterval:(
0.2
) target:self selector:
@selector
(ontime) userInfo:nil repeats:YES];
}
然后再实现定时器定时调用的ontime方法:
-(
void
)ontime{
UIImageView *view = [[UIImageView alloc] initWithImage:pic];
view.alpha =
0.5
;
int
x = round(random()
20
);
int
y = round(random()
20
);
int
s = round(random())+
10
;
int
sp =
1
/round(random()
0
)+
1
;
view.frame = CGRectMake(x, -
50
, s, s);
[self.view addSubview:view];
[UIView beginAnimations:nil context:view];
[UIView setAnimationDuration:
10
*sp];
view.frame = CGRectMake(y,
500
, s, s);
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
}
14
、配置Xcode 看程序崩溃信息
1
、在xcode中的左侧目录中找到Executables 打开
2
、双击和工程名一样的文件。
3
、在打开的文件中的Arguments选项,在下面的框中加入Name: NSZombieEnabled 设置value为YES。
15
、程序中发送邮件和检测设备邮箱是否被配置
-(
void
)addEmail{
Class mailClass = (NSClassFromString(@
"MFMailComposeViewController"
));
if
(mailClass != nil){
if
([mailClass canSendMail]){
[self displayComposerSheet];
}
else
{
[self launchMailAppOnDevice];
}
}
else
{
[self launchMailAppOnDevice];
}
}
-(
void
)displayComposerSheet
{
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.navigationBar.tag =
1002
;
[self.navigationController.navigationBar setNeedsDisplay];
controller.mailComposeDelegate = self;
[controller setSubject:@
"意见反馈"
];
[controller setToRecipients:[[NSArray alloc] initWithObjects:@
"555@cifco.net.cn"
,nil]];
NSString *emailBody = nil;
[controller setMessageBody:emailBody isHTML:YES];
[self presentModalViewController:controller animated:YES];
[controller release];
}
#pragma mark mailComposeDelegate ----
- (
void
)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
if
(result == MFMailComposeResultSent)
{
[self dismissModalViewControllerAnimated:YES];
}
if
(result == MFMailComposeResultSaved)
{
[self dismissModalViewControllerAnimated:YES];
}
if
(result == MFMailComposeResultFailed)
{
Emailalert = [[UIAlertView alloc] initWithTitle:@
""
message:@
"发送失败"
delegate:selfcancelButtonTitle:@
"知道了"
otherButtonTitles:nil];
[Emailalert show];
}
if
(result == MFMailComposeResultCancelled)
{
[self dismissModalViewControllerAnimated:YES];
}
}
- (
void
)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if
(alertView == Emailalert)
{
if
(buttonIndex == )
{
[self dismissModalViewControllerAnimated:YES];
}
}
else
{
if
(buttonIndex == )
{
}
else
{
NSString *recipients = @
"mailto:theonelgq@gmail.com?cc=theone_liuguoqing@163.com&subject=text"
;
NSString *body = @
"&body=text!"
;
NSString *email = [NSString stringWithFormat:@
"%@%@"
, recipients, body];
email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
}
}
}
#pragma mark -
#pragma mark Workaround
-(
void
)launchMailAppOnDevice
{
isEmailalert = [[UIAlertView alloc] initWithTitle:@
"警告"
message:@
"请配置您的邮箱"
delegate:selfcancelButtonTitle:@
"取消"
otherButtonTitles:@
"好的"
,nil];
[isEmailalert show];
}
16
、程序启动画面大小
iOS设备现在有三种不同的分辨率:iPhone 320x480、iPhone
4
640x960、iPad 768x1024。以前程序的启动画面(图片)只要准备一个 Default.png 就可以了,但是现在变得复杂多了。下面就是 CocoaChina 会员做得总结
如果一个程序,既支持iPhone又支持iPad,那么它需要包含下面几个图片:
Default-Portrait.png iPad专用竖向启动画面 768x1024或者768x1004
Default-Landscape.png iPad专用横向启动画面 1024x768或者1024x748
Default-PortraitUpsideDown.png iPad专用竖向启动画面(Home按钮在屏幕上面),可省略 768x1024或者768x1004
Default-LandscapeLeft.png iPad专用横向启动画面,可省略 1024x768或者1024x748
Default-LandscapeRight.png iPad专用横向启动画面,可省略 1024x768或者1024x748
Default.png iPhone默认启动图片,如果没有提供上面几个iPad专用启动图片,则在iPad上运行时也使用Default.png(不推荐) 320x480或者320x460
Default
@2x
.png iPhone4启动图片640x960或者640x920
为了在iPad上使用上述的启动画面,你还需要在info.plist中加入key: UISupportedInterfaceOrientations。同时,加入值UIInterfaceOrientationPortrait, UIInterfacOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight
17
、ASIHTTPRequest实现断点下载
- (IBAction)URLFetchWithProgress:(id)sender
{
[startButton setTitle:@
"Stop"
forState:UIControlStateNormal];
[startButton addTarget:self action:
@selector
(stopURLFetchWithProgress:)forControlEvents:UIControlEventTouchUpInside];
NSString*tempFile = [[[[NSBundle mainBundle] bundlePath]stringByDeletingLastPathComponent]stringByAppendingPathComponent:@
"MemexTrails_1.0b1.zip.download"
];
if
([[NSFileManager defaultManager] fileExistsAtPath:tempFile]) {
[[NSFileManager defaultManager] removeItemAtPath:tempFile error:nil];
}
[self resumeURLFetchWithProgress:self];
}
- (IBAction)stopURLFetchWithProgress:(id)sender
{
networkQueue = [[ASINetworkQueue alloc] init];
timer = [NSTimer scheduledTimerWithTimeInterval:
1.0
target:selfselector:
@selector
(updateBandwidthUsageIndicator) userInfo:nil repeats:YES];
timer = nil;
[startButton setTitle:@
"Stop"
forState:UIControlStateNormal];
[startButton addTarget:self action:
@selector
(URLFetchWithProgress:)forControlEvents:UIControlEventTouchUpInside];
[networkQueue cancelAllOperations];
[resumeButton setEnabled:YES];
}
- (IBAction)resumeURLFetchWithProgress:(id)sender
{
[resumeButton setEnabled:NO];
[startButton setTitle:@
"Start"
forState:UIControlStateNormal];
[startButton addTarget:self action:
@selector
(stopURLFetchWithProgress:)forControlEvents:UIControlEventTouchUpInside];
[networkQueue cancelAllOperations];
[networkQueue setShowAccurateProgress:YES];
[networkQueue setDownloadProgressDelegate:progressIndicator];
[networkQueue setDelegate:self];
[networkQueue setRequestDidFinishSelector:
@selector
(URLFetchWithProgressComplete:)];
[request setDownloadDestinationPath:[[[[NSBundle mainBundle] bundlePath]
stringByDeletingLastPathComponent] stringByAppendingPathComponent:@
"MemexTrails_1.0b1.mp3"
]];
[request setTemporaryFileDownloadPath:[[[[NSBundle mainBundle] bundlePath]stringByDeletingLastPathComponent]stringByAppendingPathComponent:@
"MemexTrails_1.0b1.zip.down"
]];
[request setAllowResumeForFileDownloads:YES];
[networkQueue addOperation:request];
[networkQueue go];
}
- (
void
)URLFetchWithProgressComplete:(ASIHTTPRequest *)request
{
if
([request error]) {
fileLocation.text=[NSString stringWithFormat:@
"An error occurred:%@"
,[[[requesterror] userInfo] objectForKey:@
"Title"
]];
}
else
{
fileLocation.text=[NSString stringWithFormat:@
"File downloaded to %@"
,[requestdownloadDestinationPath]];
}
[startButton setTitle:@
"Start"
forState:UIControlStateNormal];
[startButton addTarget:self action:
@selector
(URLFetchWithProgress:)forControlEvents:UIControlEventTouchUpInside];
}
- (IBAction)throttleBandwidth:(id)sender
{
if
([(UIButton *)sender state] ==YES) {
[ASIHTTPRequest setMaxBandwidthPerSecond:ASIWWANBandwidthThrottleAmount];
}
else
{
[ASIHTTPRequest setMaxBandwidthPerSecond:];
}
}
18
、Safari 启动本地app
在plist文件中加入URL types 结构如下图,在Safari中地址栏输入 设置的字符串,比如设置的是
QQ,地址栏输入 QQ:
19
、拖到视频进度与滑动手势冲突解决办法
#pragma mark -
#pragma mark UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
UIView *touchView = touch.view;
if
([touchView isKindOfClass:[UISlider
class
]])
{
return
NO;
}
else
{
return
YES;
}
}
20
、创建并保存Cookie的方法
NSString *cookieString = [NSString stringWithString:[headers objectForKey:@
"Cookie"
]];
NSMutableDictionary *cookieProperties = [[NSMutableDictionary alloc] init];
[cookieProperties setValue:cookieString forKey:NSHTTPCookieValue];
[cookieProperties setValue:@
"QQCookie"
forKey:NSHTTPCookieName];
[cookieProperties setValue:@
".QQ.com"
forKey:NSHTTPCookieDomain];
[cookieProperties setValue:[NSDate dateWithTimeIntervalSinceNow:
60
*
60
] forKey:NSHTTPCookieExpires];
[cookieProperties setValue:@
"/"
forKey:NSHTTPCookiePath];
NSHTTPCookie *newcookie = [[NSHTTPCookie alloc] initWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:newcookie];
21
、popover横竖屏位置改变解决办法
1
、 delegate中 处理
- (
void
)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
userImageShow = NO;
if
([popoverController isEqual:myPopover])
{
[myPopover release];
myPopover = nil;
}
}
2
、屏幕旋转时重新弹出Popover
if
(myPopover)
{
if
((self.interfaceOrientation ==
UIInterfaceOrientationLandscapeLeft) || (self.interfaceOrientation ==
UIInterfaceOrientationLandscapeRight))
{
[myPopover presentPopoverFromRect:CGRectMake(
10
,
180
,
1
,
1
)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionRight
animated:YES];
}
else
{
[myPopover presentPopoverFromRect:CGRectMake(
20
,
180
,
1
,
1
)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionRight
animated:YES];
}
}
22
、plist各种key值含义
原文:http:
UIRequiresPersistentWiFi 在程序中弹出wifi选择的key(系统设置中需要将wifi提示打开)
UIAppFonts 内嵌字体(http:
UIApplicationExitsOnSuspend 程序是否在后台运行,自己在进入后台的时候exit(
0
)是很傻的办法
UIBackgroundModes 后台运行时的服务,具体看iOS4的后台介绍
UIDeviceFamily array类型(
1
为iPhone和iPod touch设备,
2
为iPad)
UIFileSharingEnabled 开启itunes共享document文件夹
UILaunchImageFile 相当于Default.png(更名而已)
UIPrerenderedIcon icon上是否有高光
UIRequiredDeviceCapabilities 设备需要的功能(具体点击这里查看)
UIStatusBarHidden 状态栏隐藏(和程序内的区别是在于显示Default.png已经生效)
UIStatusBarStyle 状态栏类型
UIViewEdgeAntialiasing 是否开启抗锯齿
CFBundleDisplayName app显示名
CFBundleIconFile、CFBundleIconFiles 图标
CFBundleName 与CFBundleDisplayName的区别在于这个是短名,
16
字符之内
CFBundleVersion 版本
CFBundleURLTypes 自定义url,用于利用url弹回程序
CFBundleLocalizations 本地资源的本地化语言,用于itunes页面左下角显示本地话语种
CFBundleDevelopmentRegion 也是本地化相关,如果用户所在地没有相应的语言资源,则用这个key的value来作为默认
最后附上官方文档,所有的key都有,看英文原版才是正路:)点我进入
24
、xcode工程内添加多个Target
转自:http:
啥叫多Targets, 有啥用!
相信很多人都注意到XCode中,
有个Target的概念.
这在很多地方都有所体现,
比如打开一个工程后, 左侧的列表中有Targets一项, 而在工程界面的顶部菜单中,
project里面也有多个涉及到Target的项目,
那么这个Target到底是什么呢?
Apple的人是这样说的:
引用
Targets that define the products to build. A
target organizes the files and instructions needed to build a
product into a sequence of build actions that can be taken.
简单的理解的话,
可以认为一个target对应一个新的product(基于同一份代码的情况下). 但都一份代码了, 弄个新product做啥呢?
折腾这个有意思么?
其实这不是单纯的瞎折腾,
虽然代码是同一份, 但编译设置(比如编译条件), 以及包含的资源文件却可以有很大的差别. 于是即使同一份代码,
产出的product也可能大不相同.
我们来举几个典型的应用多Targets的情况吧,
比如完整版和lite版; 比如同一个游戏的
20
关,
30
关,
50
关版; 再或者比如同一个游戏换些资源和名字就当新游戏卖的(喂喂,
你在教些什么...)
Targets之间, 什么相同, 什么不同!
既然是利用同一份代码产出不同的product,
那么到底不同Target之间存在着什么样的差异呢?
要解释这个问题,
我们就要来看看一个Target指定了哪些内容.
从XCode左侧的列表中,
我们可以看到一个Target包含了Copy Bundle Resources, Compile Sources, Link
Binary With Libraries. 其中
Copy
Bundle Resources 是指生成的product的.app内将包含哪些资源文件
Compile
Sources 是指将有哪些源代码被编译
Link
Binary With Libraries 是指编译过程中会引用哪些库文件
通过Copy
Bundle Resources中内容的不同设置, 我们可以让不同的product包含不同的资源, 包括程序的主图标等,
而不是把XCode的工程中列出的资源一股脑的包含进去.
而这还不是一个target所指定的全部内容.
每个target可以使用一个独立,
不同的Info.plist文件.
我们都知道,
这个Info.plist文件内定义了一个iPhone项目的很多关键性内容, 比如程序名称,
最终生成product的全局唯一id等等.
而且不同的target还可以定义完整的差异化的编译设置,
从简单的调整优化选项, 到增加条件编译所使用的编译条件, 以至于所使用的base SDK都可以差异化指定.
创建第二个Target!
为什么是第二个?
因为第一个就是创建好工程后的默认Target呀! (废话这么多, 拖走...)
创建target有多种方法,
我们可以从现有的target上复制出一份, 然后略加改动, 也可以完全新建一个target出来. 但其实说穿了,
两个方法大同小异
首先我们来看看利用复制的方法创建target
利用复制创建target
我们在XCode左侧的列表中,
展开 Targets 项, 在现有的target上, 右键选择
"Duplicate"
, 或者选中现有target后,
在顶部菜单的Edit内选择
"Duplicate"
也可以.
此时我们就得到了一个新的target,
而在Resource里面也会得到一个 xxxx copy.plist. 这个新的target与原有的target是完全一致的,
余下的就是一些差异化的修改, 这个我们后面再说
创建全新的target
类似复制的方法,
我们可以在左侧的列表中很多地方按下右键菜单, 都可以看到Add中会有
"New Target..."
一项,
而在工程顶部菜单的Project内, 也可以看到这个
"New Target..."
的身影.
点击后,
首先会让你选择target的类型, 既然我一直所指的都是程序本身, 那么自然选择Application了(至于其他的嘛,
有兴趣的自己研究吧, 比如我们可以把程序中的部分提取成一个Static Library).
Next后,
会让你输入一个新的Target的名字, 而不像复制的方法中, 默认生成 xxxxx copy这样的target名.
但是这样生成出的Target几乎是空的.
Copy Bundle Resources, Compile Sources, Link Binary With
Libraries里面都没有任何内容. 编译设置也是完全原始的状态.
可以通过拖拽内容到这些target的设置中,
以及调整编译选项来完成Target的配置.
Target中部分内容的修改方法!
其实这段的部分内容,
在非多Targets的工程中也可能会用得到.
由于修改基本都是在工程/编译设置中完成,
因此没有特殊情况, 就不再声明了, 打开target对应的工程/编译设置的方法可以采用在该target上右键, 选择get
info来做到.
生成的product名称的修改:
Packing段内的Product Name一项
Info.plist文件名:
Packing段内的Info.plist File一项, 比如复制出来的target觉得那个xxxxx
copy.plist太傻就可以在这里改
条
件编译: 增加一个User-Defined Setting(Target
"xxxx"
Info的build页的左下角那个齿轮中可以看到这个内容), 在Other C Flag里面填入,
比如要定义一个叫做LITE_VERSION的define值, 我们可以写上
"-DLITE_VERSION"
或
"-DLITE_VERSION=1"
. 那么在程序中就可以用
#
if
defined(LITE_VERSION)
#
else
#endif
这样的条件编译来部分差异化代码了
也许有些朋友记得我在代码区贴过的检测破解版的代码,
其中有一种检测方法就是看info.plist是文本还是二进制的, 那么我们能否建议一个模拟破解的target,
直接生成文本的info.plist以便测试呢?
当然可以,
在packing段内, 有一项叫
"Info.plist Output Encoding"
, 默认值是Binary,
我们只要选成xml, 那么生成出的product.app内的info.plist就直接是文本样式的了.
另
外, 向Copy Bundle Resources, Compile Sources, Link Binary With
Libraries内添加/删除文件, 可以在要改动的文件上, 选择get info, 并且切换到Target页,
勾选要引用这个文件的target即可. 比如icon.png可以指定给默认target, 而icon_lite.png指定给lite
verion的target
大致就是如此吧, 懒得抓图了. 各位将就吧. 想到什么需要补充的, 我会加入
另外
一个英文教程:http:
25
、详解IOS SDK兼容性引导
转自: http:
IOS SDK兼容性引导是本文要介绍的内容,主要是基于IOS SDK基础的开发介绍说明如何应用于XCode工程的基于IOS SDK开发的技术。来看详细内容讲解。
1
、用(weakly linked)弱连接类、方法和函数来支持在不同版本之间的程序运行
2
、弱连接整个框架(framework)
3
、为不同的IOS SDK选择不同的编译条件
4
、在代码中找出过时API的使用
5
、确定在运行时操作系统和框架(framework)的版本
一 、在IOS中使用弱连接类
在工程中使用类的弱连接的时候必须确保这些类在运行时的可用性,要不会引起动态连接的错误。
在IOS4.
2
以后的版本都是使用NSObject
class
的方法来检测弱连接在运行时态的可用性,这种简单高效的机制使用了NS_CLASS_AVAILABLE的可用性宏。
检测最近release的framework还不支持NS_CLASS_AVAILABLE的宏
在支持NS_CLASS_AVAILABLE的宏framework的条件编译中,可以如下的使用
if
([UIPrintInteractionController
class
]) {
}
else
{
}
如果你在不确保是否已经可以使用类方法的时候你可以使用NSClassFromString 方法来判断,使用方法如下:
Class cls = NSClassFromString (@
"NSRegularExpression"
);
if
(cls) {
}
else
{
}
二、在方法,函数和符号中使用弱连接
和使用类的弱连接一样,在使用它之前要确保方法函数和符号在运行时的可用性,要不在编译的时候会报错动态连接错误,假设你想使用新版本IOS
SDK的特性但是又想能够运行在低版本的SDK中,那么就要对早期的版本设置相应的开发target,在Object-c中
instancesRespondToSelector:
方法告诉我们所给的方法是否可用,例如:使用availableCaptureModesForCameraDevice:这个方法(在
4.0
以后才是可
用的),我们可以这样使用它。
1
、检查一个Object-c方法的可用性
if
([UIImagePickerController instancesRespondToSelector:
@selector
(availableCaptureModesForCameraDevice:)]) {
}
else
{
}
判断一个弱连接的C函数是否可用,只要判断函数的地址是否返回为NULL,以CGColorCreateGenericCMYK 函数为例,我们可以像以下那样使用。
2
、检查C方法的可用性
if
(CGColorCreateGenericCMYK != NULL) {
CGColorCreateGenericCMYK (
0.1
,
0.5
.
0.0
,
1.0
,
0.1
);
}
else
{
}
要检测一个C方法是否可用,比较明确的为地址是否为NULL或零。你不能使用反运算符(!)来否定一个函数的可用性
检测一个 external(extern)常量或一个通知的名字应当比较它的地址(address)--而不是符号的名称, 判断是否为NULL or nil
三、弱连接整个Framework
比如一个在高版本中才出现的Framework,想在低版本使用他的特性。那你就必须弱连接那个使用的Framework,详见官方的图解---(其实就是在添加进去的Framework的 required 改成 optional)
http:
130
-Files_in_Projects/project_files.html#
四、条件编译
for
不同的SDK
如果你不止基于一个IOS SDK编译,你就可能需要为base
sdk使用条件化,可以使用在Availability.h中的定义。这个.h文件存在于系统的文件夹/usr/include的文件夹下,例如想在
Mac OS X v10.
5
(而不是IOS)中使用函数 CGColorCreateGenericCMYK
使用预处理指令
for
条件编译
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
#
if
__MAC_OS_X_VERSION_MAX_ALLOWED >=
1050
if
(CGColorCreateGenericCMYK != NULL) {
CGColorCreateGenericCMYK(
0.1
,
0.5
.
0.0
,
1.0
,
0.1
);
}
else
{
#endif
#
if
__MAC_OS_X_VERSION_MAX_ALLOWED >=
1050
}
#endif
#endif
}
五、寻找出在程序中使用的以过时的实例
在IOS或Mac
OS中有时候API会过时,但是过时不代表着那些就从Library或framework中删除,但是在使用的过程中会报出warning,并且在不远的
将来可能会被Apple从中移除。例如我们在code中使用了过时的函数 HPurge那么就会报出如下
'HPurge'
is deprecated (declared at /Users/steve/MyProject/main.c:
51
)
所以我们应当在工程中查找出如下的警告并且修改。
六、确定操作系统和Framework的版本
在运行时检查IOS的版本
NSString *osVersion = [[UIDevice currentDevice] systemVersion];
在运行时检查Mac OS X用Gestalt function 和 系统版本常量
另外,对于许多的Framework你可以在运行时检查指定Framework的版本。
例如:Application Kit(NSApplication.h)定义了NSAppKitVersionNumber常量---可以用来检查Application Kit Framework的版本
如
APPKIT_EXTERN
double
NSAppKitVersionNumber;
#define NSAppKitVersionNumber10_0
577
#define NSAppKitVersionNumber10_1
620
#define NSAppKitVersionNumber10_2
663
#define NSAppKitVersionNumber10_2_3
663.6
#define NSAppKitVersionNumber10_3
743
#define NSAppKitVersionNumber10_3_2
743.14
#define NSAppKitVersionNumber10_3_3
743.2
#define NSAppKitVersionNumber10_3_5
743.24
#define NSAppKitVersionNumber10_3_7
743.33
#define NSAppKitVersionNumber10_3_9
743.36
#define NSAppKitVersionNumber10_4
824
#define NSAppKitVersionNumber10_4_1
824.1
#define NSAppKitVersionNumber10_4_3
824.23
#define NSAppKitVersionNumber10_4_4
824.33
#define NSAppKitVersionNumber10_4_7
824.41
#define NSAppKitVersionNumber10_5
949
#define NSAppKitVersionNumber10_5_2
949.27
#define NSAppKitVersionNumber10_5_3
949.33
所以我们可以像如下使用:
if
(floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_0) {
}
else
if
(floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) {
}
else
if
(floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_2) {
}
else
if
(floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_3) {
}
else
if
(floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4) {
}
else
if
(floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_5) {
}
else
{
}
跟以上一样在 NSObjCRuntime.h中用定义了NSFoundationVersionNumber全局常量
小结:详解IOS SDK兼容性引导的内容介绍玩玩了,希望通过本文的学习能对你有所帮助!
原文地址:http:
26
、NSDate 与 NSString 转换
将字符串 “Fri Nov
11
09
:
06
:
27
+
0800
2011
” 转换成Date:
NSDateFormatter *format = [[NSDateFormatter alloc] init];
NSLocale *enLocale = [[NSLocale alloc] initWithLocaleIdentifier:@
"en-US"
];
[format setLocale:enLocale];
[enLocale release];
[format setDateFormat:@
"EEE MMM dd HH:mm:ss ZZZ yyyy"
];
NSDate *dateTime = [format dateFromString:message];
将Date转换成字符串:
NSDate *date = [NSDate date];
NSString * dateString = [format stringFromDate:date];
27
、数组中存储数据查询
NSMutableDictionary *userDic1 = [NSMutableDictionary dictionaryWithCapacity:
10
];
NSMutableDictionary *userDic2 = [NSMutableDictionary dictionaryWithCapacity:
10
];
[userDic1 setValue:@
"Li"
forKey:@
"name"
];
[userDic2 setValue:@
"Wang"
forKey:@
"name"
];
NSArray *userArray = [NSArray arrayWithObjects:userDic1,userDic2,nil];
NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@
"SELF.name contains[cd] %@ "
,@
"L"
];
NSMutableArray *searchArray = [NSMutableArray arrayWithArray:[userArray filteredArrayUsingPredicate:namePredicate]];
NSLog(@
"searchArray == %@"
,searchArray);