1. 框架的可用性检查
弱链接某框架(方法:targets--Bulid Phases--Link Binary With Libraries,在需要使用弱链接的框架上,把默认的Required,改成Optional)
2. 类的可用性检查
id myObj = [[NSClassFromString(@"NSLayoutManager") alloc] init]; // 在iOS6上运行,myObj是nil
id myObj = [[NSLayoutManager alloc] init]; // 在iOS6上编译会出错
3. 方法的可用性检查
if ([self.view respondsToSelector:@selector(setTintColor:)]) {
// to do
}
注:如果检查的方法是C全局函数,应该像下面这样
if (CFunction != NULL){
CFunction(a);zs
}
不能隐式的假定CFunction指针为nil或NULL,也就是说不能像下面这样
if (CFunction){
CFunction(a);
}
也不能使用带圆括号的CFunction,也就是说不能像下面这样
if ( CFunction() != NULL){
CFunction(a);
}
4. 检查设备功能
不要通过设备类型或设备型号去判断设备功能(麦克风,摄像头等等)
4.1 UIDevice+Additions.h
#import <UIKit/UIKit.h>
@interface UIDevice (Additions)
/**
* 麦克风可不可用
*/
- (BOOL)add_microphoneAvailable;
/**
* 控制器的ViewDidload里实现下面方法,即可监听插入麦克风的事件
*
* @param then 监听到麦克风插入事件的回调方法
*/
- (void)add_externalMicrophoneAndThen:(void(^)())then;
/**
* 检查摄像头可不可用
*/
- (BOOL)add_cameraAvailable;
/**
* 检查前置摄像头可不可用
*/
- (BOOL)add_frontCameraAvailable;
/**
* 检查摄像头支不支持视频录制
*/
- (BOOL)add_videoCameraAvailable;
/**
* 检查相册是否为空
*/
- (BOOL)add_emptyPhotoLibrary;
/**
* 检查闪光灯可不可用
*/
- (BOOL)add_cameraFlashAvailable;
/**
* 检查陀螺仪可不可用
*/
- (BOOL)add_gyroscopeAvailable;
/**
* 检查指南针可不可用
*/
- (BOOL)add_compassAvailable;
/**
* 检查是不是retina屏幕
*/
- (BOOL)add_retinaDisplayCapable;
/**
* 震动1:在iphone上震动,在ipad、ipod上发出"哔哔"的响声
*/
- (void)add_vibrateType1;
/**
* 震动2:在iphone上震动,在ipad、ipod上什么也不做
*/
- (void)add_vibrateType2;
/**
* 检查能不能打电话
*/
- (BOOL)add_canMakePhoneCalls;
/**
* 检查能不能发短信
*/
- (BOOL)add_canSendText;
/**
* 检查能不能发邮件
*/
- (BOOL)add_canSendMail;
@end
4.2 UIDevice+Additions.m
#import "UIDevice+Additions.h"
#import <AVFoundation/AVFoundation.h>
#import <CoreMotion/CoreMotion.h>
#import <CoreLocation/CoreLocation.h>
#import <AudioToolbox/AudioToolbox.h>
#import <MessageUI/MessageUI.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <objc/runtime.h>
@implementation UIDevice (Additions)
- (BOOL)add_microphoneAvailable
{
return [[AVAudioSession sharedInstance] isInputAvailable];
}
static char thenBlockKey;
- (void (^)())thenBlock
{
return objc_getAssociatedObject(self, &thenBlockKey);
}
- (void)setThenBlock:(void(^)())thenBlock
{
objc_setAssociatedObject(self, &thenBlockKey, thenBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
static id mySelf;
- (void)add_externalMicrophoneAndThen:(void(^)())then
{
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable,audioInputPropertyListener,nil);
if(then != nil){
self.thenBlock = then;
}
}
void audioInputPropertyListener(void *inClientData,AudioSessionPropertyID inID,UInt32 inDataSize,const void *inData)
{
UInt32 isAvailable = *(UInt32 *)inData;
BOOL micAvailable = (isAvailable > 0);
// 怎么让block在这里被调用 ?
}
- (BOOL)add_cameraAvailable
{
return [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
}
- (BOOL)add_frontCameraAvailable
{
#ifdef __IPHONE_4_0
return [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront];
#else
return NO;
#endif
}
- (BOOL)add_videoCameraAvailable
{
if (![self add_cameraAvailable]) {
return NO;
}
NSArray *sourceTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
if (![sourceTypes containsObject:(NSString *)kUTTypeMovie]) {
return NO;
}
return YES;
}
- (BOOL)add_emptyPhotoLibrary
{
return [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary];
}
- (BOOL)add_cameraFlashAvailable
{
return [UIImagePickerController isFlashAvailableForCameraDevice:UIImagePickerControllerCameraDeviceRear];
}
- (BOOL)add_gyroscopeAvailable
{
CMMotionManager *mgr = [[CMMotionManager alloc]init];
BOOL gyroscopeAvailable = mgr.gyroAvailable;
return gyroscopeAvailable;
}
- (BOOL)add_compassAvailable
{
return [CLLocationManager headingAvailable];
}
- (BOOL)add_retinaDisplayCapable
{
int scale = 1.0;
UIScreen *screen = [UIScreen mainScreen];
if ([screen respondsToSelector:@selector(scale)]) {
scale = screen.scale;
if (scale == 2.0f) {
return YES;
} else {
return NO;
}
}
return NO;
}
/**
* 在iphone上震动,在ipad、ipod上发出"哔哔"的响声
*/
- (void)add_vibrateType1
{
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}
/**
* 在iphone上震动,在ipad、ipod上什么也不做
*/
- (void)add_vibrateType2
{
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
- (BOOL)add_canMakePhoneCalls
{
return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://10086"]];
}
- (BOOL)add_canSendText
{
return [MFMessageComposeViewController canSendText];
}
- (BOOL)add_canSendMail
{
return [MFMailComposeViewController canSendMail];
}
@end
单个VC的iOS版本适配:
xcode5 中的界面布局 根据sdk 分成ios7.0 and Later 和 ios6.1 and Earlier 两种,那如何xib同时支持 ios6 和ios7 的界面呢
方法如下:
在xcode5 中分别创建两个 xib文件 和对应的ViewControl关联, 这两个xib文件一个支持ios6 一个支持ios7
在跳转本界面时,在代码里面实现如下:
float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; if (systemVersion >= 7.0) { AboutUSView *aboutUSView= [[[AboutUSView alloc] initWithNibName:@"AboutUSView1" bundle:nil] autorelease]; [self.navigationController pushViewController:aboutUSView animated:TRUE]; } else { AboutUSView *aboutUSView= [[[AboutUSView alloc] initWithNibName:@"AboutUSView" bundle:nil] autorelease]; [self.navigationController pushViewController:aboutUSView animated:TRUE]; }