
首先要知道的是,您需要查看是否存在所需的硬件或传感器,而不是假设设备会做什么. 例如,您不能假设只有iPhone具有麦克风. 相反,您应该使用API查看麦克风是否存在. 以下代码的第一个优点是,它与将来将要引入的新设备和外部麦克风自动兼容.
第二个优势呢?这段代码只有一行.
检查麦克风可用性的正确方法
1 2 3 4
- (BOOL) microphoneAvailable {
AVAudioSession *session = [AVAudioSession sharedInstance];
return session.inputIsAvailable;
}
对于麦克风,还需要提醒您输入设备中的更改. 也就是说,当用户插入麦克风时,除了在viewDidAppear中进行相应的修改外,还必须激活UI上的“记录”按钮. 听起来很酷apple硬件检测,不是吗?下面是具体的实现方法.
检查麦克风是否已插入
1 2 3 4 5 6 7 8 9 10 11 12
void audioInputPropertyListener(void* inClientData,
AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData) {
UInt32 isAvailable = *(UInt32*)inData;
BOOL micAvailable = (isAvailable > 0);
//加入更新UI的代码
}
- (void)viewDidLoad {
[super viewDidLoad];
AudioSessionAddPropertyListener(
kAudioSessionProperty_AudioInputAvailable,
audioInputPropertyListener, nil);
}
在这里,您要做的就是为kAudioSessionProperty_AudioInputAvailable添加一个属性侦听器,然后在回调中检查其值.
仅需几行代码,就可以编写正确的设备检测代码. 接下来,您需要扩展此代码以支持其他硬件和传感器.

使用AudioSessionPropertyListeners类似于观看NSNotification事件. 将属性侦听器添加到类时,您有责任在适当时删除它. 在上一个示例中,由于属性侦听器已添加到viewDidLoad中,因此需要在didReceiveMemoryWarning方法中将其删除.
iPhone最初仅具有,后来在iPhone 4中添加了前置. iPodtouch直到第四代才具有. iPhone 4带有前置,但iPad 1(比iPhone 4更大)没有,而后来的iPad 2带有前置和后置. 所有这些意味着您不应编写假设设备功能的代码. 实际上,使用API更方便.
UIImagePickerController类包含用于检查源类型的可用性的类方法.
检测摄像机是否存在
1 2 3 4
- (BOOL) cameraAvailable {
return [UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera];
}
检测前置的存在
1 2 3 4 5 6 7 8 9
- (BOOL) frontCameraAvailable
{
#ifdef __IPHONE_4_0
return [UIImagePickerController isCameraDeviceAvailable:
UIImagePickerControllerCameraDeviceFront];
#else
return NO;
#endif
}
检测前置. 它需要在iOS 4或更高版本上运行. 枚举类型UIImagePickerControllerCameraDeviceFront仅在iOS 4和更高版本中可用,因为所有带有前置的设备(iPhone 4和iPad 2)都使用iOS 4和更高版本. 因此,如果设备使用的是iOS 3或更低版本,则可以使用宏并返回NO.
类似地,您可以检查设备上的相机是否可以进行视频录制. iPhone 3GS和更新的相机支持录制视频. 您可以使用以下代码进行检查.

检测相机是否支持视频记录
1 2 3 4 5 6 7 8 9 10 11 12 13
- (BOOL) videoCameraAvailable {
UIImagePickerController *picker =
[[UIImagePickerController alloc] init];
// 首次调用前面的方法,检查是否存在
if(![self cameraAvailable]) return NO;
NSArray *sourceTypes = [UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypeCamera];
if (![sourceTypes containsObject:(NSString *)kUTTypeMovie]){
return NO;
}
return YES;
}
此代码将枚举给定相机的可用媒体类型,并确定其中是否包含kUTTypeMovie.
如果您使用相机,则几乎总是会使用照片库. 在调用UIImagePicker显示用户相册之前,需要确保其中包含照片. 您可以通过检查相机是否存在来检查相册是否为空. 只需传递UIImagePickerControllerSourceSourceTypePhotoLibrary或UIImagePickerControllerSourceTypeSavedPhotosAlbum作为源类型即可.
到目前为止,唯一带有相机闪光灯的设备是iPhone 4 ^ [1] ^. 在未来几年中,将会有越来越多的设备配备相机闪光灯. 使用UIImagePickerController的类方法来检查相机闪光灯的存在很容易.
^ [1] ^翻译本书时,iPhone 4S和iPhone 5均已发布,并且还带有照相机闪光灯. -译者注
检测到相机闪光灯的存在
1 2 3 4 5 6 7 8
- (BOOL) cameraFlashAvailable {
#ifdef __IPHONE_4_0
return [UIImagePickerController isFlashAvailableForCameraDevice:
UIImagePickerControllerCameraDeviceRear];
#else
return NO;
#endif
}
陀螺仪是iPhone 4上一个有趣的新传感器. 在iPhone 4之后发布的设备(包括新的iPad和iPhone 5)都装有陀螺仪. 陀螺仪用于测量设备物理位置的相对变化. 相反,加速度计只能测量力的大小,而不能测量扭力. 使用陀螺仪,游戏开发人员甚至可以实现六轴控制,类似于Sony PlayStation 3控制器或任天堂的Wii控制器提供的功能. 您可以使用CoreMotion.framework提供的API来检测陀螺仪的存在.

检测陀螺仪的存在
1 2 3 4 5 6 7 8 9
- (BOOL) gyroscopeAvailable {
#ifdef __IPHONE_4_0
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
BOOL gyroAvailable = motionManager.gyroAvailable;
return gyroAvailable;
#else
return NO;
#endif
}
如果陀螺仪是应用程序中的重要功能,并且目标设备上没有陀螺仪,则必须使用其他输入法来设计应用程序. 或者,您可以在应用程序的info.plist的UIRequiredDeviceCapablities键中指定它们,以防止没有陀螺仪的设备安装该应用程序. 该密钥将在本章后面进一步说明.
可以使用CoreLocation.framework中的CLLocationManager类检查指南针的可用性. 在CLLocationManager中调用headingAvailable方法. 如果返回值为true,则可以在应用程序中使用指南针. 指南针在与位置相关的应用程序和使用增强现实的应用程序中更有用.
作为iOS开发人员,您已经知道,只要为应用程序中使用的每个资源添加一个@ 2x图像文件,就可以满足Retina Display的需求. 但是,如果要从远程服务器下载图片,则具有视网膜屏幕的设备需要下载分辨率是普通屏幕图片两倍的图片.
一个很好的例子是照片浏览器应用程序,它类似于Flickr浏览器或Instagram. 当用户在iPhone 4,新iPad或iPhone 5上启动该应用程序时,下载图像的分辨率应该是非视网膜屏幕设备上图像分辨率的两倍. 一些开发人员选择忽略它,而直接为所有设备下载高分辨率图像,但这有点浪费带宽,甚至在通过EDGE下载时甚至会慢很多. 相反,您应该在确定设备正在使用视网膜屏幕之后下载高分辨率图像. 这项检查很容易.
检查设备是否使用视网膜屏幕
1 2 3 4 5 6 7 8
- (BOOL) 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;
}
在此代码中,您将找到设备的主屏幕,然后检查设备是否可以显示适合视网膜屏幕的高分辨率图片. 这样,如果Apple引入了外部视网膜屏幕(也许是较新的Apple Cinema显示器),以直接视网膜模式输出支持当前一代的iPad,那么您的应用程序仍将可以正常运行,无需任何修改.

在撰写本文时,每个版本中只有iPhone版本具有振动警报功能. 不幸的是apple硬件检测,没有公开可用的API来检测设备是否支持振动功能. 但是,AudioToolbox.framework有两种方法可以选择性地振动不同版本的iPhone:
1 2
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
第一种方法将振动iPhone,在iPod touch / iPad上它将发出蜂鸣声. 第二种方法只会振动iPhone. 在不支持振动的设备上,它什么也不做. 如果您正在开发使用振动设备向您发出危险警报的游戏,或者当迷宫游戏在玩家撞墙时发生振动,那么您应该使用第二种方法. 第一种方法用于警告用户,包括振动和蜂鸣声,而第二种方法只能用于引起振动.
iOS应用程序可以处理通过按下外部耳机上的按钮触发的远程控制事件. 要处理此类事件,请使用以下方法来接收通知:
1
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
在firstResponder中实现以下方法:
1
remoteControlReceivedWithEvent:
调用以下方法以确保在不需要这些事件时关闭该功能:
1
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
您可以通过检查设备是否可以打开电话来检查它是否支持拨打电话: 键入URL. UIApplication类的canOpenURL: 方法可轻松检查设备上是否存在可以处理特定类型URL的应用程序. 在iPhone上,电话: 这种类型的URL由iPhone上的电话应用程序处理. 此方法还可用于检查设备上是否安装了能够处理给定URL的特定应用程序.
检测电话
1 2 3 4
- (BOOL) canMakePhoneCalls {
return [[UIApplication sharedApplication]
canOpenURL:[NSURL URLWithString:@"tel://"]];
}
可用性提示在iPod touch上,开发人员应完全隐藏面向电话的功能. 例如,如果您开发了一个黄页应用程序,该应用程序显示了Internet上的电话号码列表,则应仅在可以拨打电话的设备上显示拨打电话的按钮. 不要只是禁用它(因为用户无法对其启用任何功能)或显示错误警报. 有一个先例,在iPod touch上显示“ Not a iPhone”错误提示将阻止该应用通过Apple的应用审查部门.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shumachanpin/article-160210-1.html
埋怨命苦真悲哀
求个关注谢谢
沙特支持的IS
我们一直都在