[转]iphone和配件进行通讯,外接设备开发

转自:http://blog.sina.com.cn/s/blog_6ae8b50d0100t1tu.html

iphone和配件进行通讯,外接设备开发

  (2011-07-25 14:09:50)

设备支持

iPhone OS支持很多使移动计算的用户体验更具吸引力的特性。通过iPhone OS,应用程序可以访问诸如加速计和照相机这样的硬件特性,也可以访问像用户照片库这样的软件特性。本文的下面部分将描述这些特性,并向您展示如何将它们集成到您的应用程序中。

确定硬件支持是否存在

为iPhone OS设计的应用程序必须能够运行在具有不同硬件特性的多种设备上。虽然像加速计和Wi-Fi连网这样的特性在所有设备上都是支持的,但是一些设备不包含照 相机或GPS硬件。如果您的应用程序要求设备具有这样的特性,应该在用户购买之前通知他们。对于那些不是必需、但如果存在就希望支持的特性,则必须在试图 使用之前检测它们是否存在。

重要提示:如果应用程序运行的前提是某个特性一定要存在,则应该在应用程序的Info.plist文件中对UIRequiredDeviceCapabilities键进行相应的设置,以避免将需要某种特性的应用程序安装在不具有该特性的设备上。但是,如果您的应用程序在给定特性存在或不存在时都可以运行,则不应该包含这个键。更多有关如果配置该键的信息,请参见“信息属性列表”部分。

表8-1列出了确定某种硬件是否存在的方法。如果您的应用程序在缺少某个特性时可以工作,而在该特性存在时又可以加以利用,则应该使用这些技术。

表8-1  识别可用的硬件特性

特性

选项

确定网络是否存在...

使用Software Configuration框架的可达性(reachability)接口检测当前的网络连接。有关如何使用Software Configuration框架的例子请参见可达性部分。

确定静态照相机是否存在...

使用UIImagePickerController类的isSourceTypeAvailable:方法来确定照相机是否存在。更多信息请参见“使用照相机进行照相”部分。

确定音频输入(麦克风)是否存在…

在iPhone OS 3.0及之后的系统上,可以用AVAudioSession类来确定音频输入是否存在。该类考虑了iPhone OS设备上的很多不同的音频输入设备,包括内置的麦克风、耳机插座、和连接的配件。更多信息请参见AVAudioSession类参考部分。

确定GPS硬件是否存在…

在配置CLLocationManager对象、使应用程序可以获取位置变化时,指定高精度级别。Core Location框架并不指定硬件是否存在的直接信息,而是使用精度值来提供您所需要的数据。如果一系列位置事件报告的精度都不够高,您可以通知用户。更多信息请参见“获取用户的当前位置”部分。

确定特定的配件是否存在…

使用External Accessory框架的类来寻找合适的附近对象,并进行连接。更多信息请参见“和配件进行通讯”部分。

和配件进行通讯

在iPhone OS 3.0及之后的系统上,External Accessory框架(ExternalAccessory.framework)提供了一种管道机制,使应用程序可以和iPhone或iPod touch设备的配件进行通讯。通过这种管道,应用程序开发者可以将配件级别的功能集成到自己的程序中。

请注意:下面部分将向您展示iPhone应用程序如何连接配件。如果您有兴趣成为iPhone或iPod touch配件的开发者,可以在http://developer.apple.com网站上找到相应的信息。

为了使用External Accessory框架的接口,您必须将ExternalAccessory.framework加入到Xcode工程,并连接到相应的目标中。此外,还需要在相应的源代码文件的顶部包含一个#import <ExternalAccessory/ExternalAccessory.h>语句,才能访问该框架的类和头文件。有关如何为工程添加框架的更多信息,请参见Xcode工程管理指南中的工程中的文件部分;有关External Accessory框架中类的一般信息,请参见External Accessory框架参考

配件的基础

在和配件进行通讯之前,需要与配件的制造商紧密合作,理解配件提供的服务。制造商必须在配件的硬件中加入显式的支持,才能和iPhone OS进行通讯。作为这种支持的一部分,配件必须支持至少一种命令协议,也就是支持一种定制的通讯模式,使配件和应用程序之间可以进行数据传输。苹果并不维护一个协议的注册表,支持何种协议及是否使用其他制造商支持的定制或标准协议是由制造商自行决定的。

作为和配件制造商通讯的一部分,您必须找出给定的配件支持什么协议。为了避免名字空间发生冲突,协议的名称由反向的DNS字符串来指定,形式是com.apple.myProtocol。这使得每个配件制造商都可以根据自己的需要定义协议,以支持不同的配件产品线。

应用程序通过打开一个使用指定协议的会话来和配件进行通讯。打开会话的方法是创建一个EASession类的实例,该类中包含NSInputStreamNSOutputStream对象,可以和配件进行通讯。通过这些流对象,应用程序可以向配件发送未经加工的数据包,以及接收来自配件的类似数据包。因此,您必须按照期望的协议来理解每个数据包的格式。

声明应用程序支持的协议

能够和配件通讯的应用程序应该在其Info.plist文件中声明支持的协议,使系统知道在相应的配件接入时,该应用程序可以被启动。如果当前没有应用程序可以支持接入的配件,系统可以选择启动App Store并指向支持该设备的应用程序。

为了声明支持的协议,您必须在应用程序的Info.plist文件中包含UISupportedExternalAccessoryProtocols键。该键包含一个字符串数组,用于标识应用程序支持的通讯协议。您的应用程序可以在这个列表中以任意顺序包含任意数量的协议。系统并不使用这个列表来确定应用程序应该选择哪个协议,而只是用它来确定应用程序是否能够和相应的配件进行通讯。您的代码需要在开始和配件进行对话时选择适当的通讯协议。

在运行时连接配件

在配件接入系统并做好通讯准备之前,通过External Accessory框架无法看到配件。当配件变为可见时,您的应用程序就可以获取相应的配件对象,然后用其支持的一或多个协议打开会话。

共享的EAAccessoryManager对象为应用程序寻找与之通讯的配件提供主入口点。该类包含一个已经接入的配件对象的数组,您可以对其进行枚举,看看是否存在应用程序支持的配件。EAAccessory对象中的绝大多数信息(比如名称、制造商、和型号信息)都只是用于显示。如果您要确定应用程序是否可以连接一个配件,必须看配件的协议,确认应用程序是否支持其中的某个协议。

请注意:多个配件对象支持同一协议是可能的。如果发生这种情况,您的代码必须负责选择使用哪个配件对象。

对于给定的配件对象,每次只能有一个指定协议的会话。EAAccessory对象的protocolStrings属性包含一个字典,字典的键是配件支持的协议。如果您试图用一个已经在使用的协议创建会话,External Accessory框架就会产生错误。

程序清单8-1展示了如何检查接入配件的列表并从中取得应用程序支持的第一个配件。它为指定的协议创建一个会话,并对会话的输入和输出流进行配置。在这个方法返回会话对象时,已经完成和配件的连接,并可以开始发送和接收数据了。

程序清单8-1  创建和配件的通讯会话

- (EASession *)openSessionForProtocol:(NSString *)protocolString
{
NSArray *accessories = [[EAAccessoryManager sharedAccessoryManager]
connectedAccessories];
EAAccessory *accessory = nil;
EASession *session = nil;
 
for (EAAccessory *obj in accessories)
{
if ([[obj protocolStrings] containsObject:protocolString])
{
accessory = obj;
break;
}
}
 
if (accessory)
{
session = [[EASession alloc] initWithAccessory:accessory
forProtocol:protocolString];
if (session)
{
[[session inputStream] setDelegate:self];
[[session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[[session inputStream] open];
[[session outputStream] setDelegate:self];
[[session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[[session outputStream] open];
[session autorelease];
}
}
 
return session;
}

在配置好输入输出流之后,最好一步就是处理和流相关的数据了。程序清单8-2展示了在委托方 法中处理流事件的基本代码结构。清单中的方法可以响应来自配件输入输出流的事件。当配件向应用程序发送数据时,事件发生表示有数据可供读取;类似地,当配 件准备好接收应用程序数据时,也通过事件来表示(当然,您并不一定要等到这个事件发生才向流写出数据,应用程序也可以调用流的hasBytesAvailable方法来确认配件是否还能够接收数据)。有关流及如何处理流事件的更多信息,请参见Cocoa流编程指南

程序清单8-2  处理流事件

// Handle communications from the streams.
- (void)stream:(NSStream*)theStream handleEvent:(NSStreamEvent)streamEvent
{
switch (streamEvent)
{
case NSStreamHasBytesAvailable:
// Process the incoming stream data.
break;
 
case NSStreamEventHasSpaceAvailable:
// Send the next queued command.
break;
 
default:
break;
}
 
}

监控与配件有关的事件

当配件接入或断开时,External Accessory框架都可以发送通告。但是这些通告并不自动发送,如果您的应用程序感兴趣,必须调用EAAccessoryManager类的registerForLocalNotifications方法来显式请求。当配件接入、认证、并准备好和应用程序进行交互时,框架可以发出一个EAAccessoryDidConnectNotification通告;而当配件断开时,框架则可以发送一个EAAccessoryDidDisconnectNotification通告。您可以通过缺省的NSNotificationCenter来注册接收这些通告。两种通告都包含受影响的配件的信息。

除了通过缺省的通告中心接收通告之外,当前正在和配件进行交互的应用程序可以为相应的EAAccessory对象分配一个委托,使它在发生变化的时候得到通知。委托对象必须遵循EAAccessoryDelegate协议,该协议目前包含名为accessoryDidDisconnect:的可选方法,您可以通过这个方法来接收配件断开通告,而不需要事先配置通告观察者。

有关如何注册接收通告的更多信息,请参见Cocoa通告编程主题

帮助文档:http://www.apple.com.cn/developer/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/AdvancedFeatures/AdvancedFeatures.html#//apple_ref/doc/uid/TP40007072-CH14-SW20

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值