ios - 我应该如何构建我的应用程序来处理传入的蓝牙数据?

标签 ios objective-c bluetooth bluetooth-lowenergy core-bluetooth

我正在开展一个项目,其中我有一个应用程序可以通过 BLE 从可穿戴外围设备接收数据,但我正在为如何构建该应用程序而苦苦挣扎。目前我有一个单例 BLEManager 类,它不断地在后台接收数据,然后使用 NSNotificationCenter 将其发送到事件 View Controller 。这可行,但变得困惑并且看起来不理想,因为我有多个 View Controller ,每个 View Controller 都以相同的方式处理数据,然后以不同的方式显示它。此外,还有一些与数据处理相关的设置可以在应用程序中更改,并且需要在所有地方都相同。如果 BLEManager 将数据发送到中央处理类,然后将处理后的数据发送到事件 View Controller ,那就太好了,但我不确定设置它的最佳方法。

我可以将所有处理合并到 BLEManager 类中,但这样它会变得非常臃肿和不直观,并且不会很好地继续前进。如果我创建一个单独的处理类,这是 BLEManager 的一个属性,那么如果我想从其他任何地方获取或更改处理类中的任何变量,我必须通过 BLEManager,这很烦人。我可以制作一个单例处理类,从 BLEManager 接收数据,然后将其发送到事件 VC,但我看到有人说要避免单例,所以我犹豫要不要使用另一个,尽管这看起来可能是一个很好的选择解决方案。

是否有标准或推荐的方法来构建 iOS 应用程序以处理来自蓝牙的传入数据,然后将其发送到需要的地方?

最佳答案

如果您创建一个大型系统来与 BLE(以及其他)通信,BLEManager 根本不应该是一个单例。这需要是一个能够处理所有蓝牙通信的对象(我相信它已经做到了)并通过委托(delegate)报告相关数据。

此时你需要的是这个对象的接口(interface),在你的情况下最好是一个单例。此类应具有管理这些数据所需的最小化接口(interface),并且根本不应公开 BLEManager。这意味着创建所有方法,例如 BLEManager 的初始化,这从使用的角度来看是有意义的。在某些情况下,这将复制您已经在 BLEManager 中完成的界面部分,并且某些方法很可能只是将消息转发给管理器。

这个接口(interface)类一开始可能看起来有点无用,但最终它会救你的命。你应该放在这个类中的是所有其他可能的附件,例如本地数据库管理器、API 管理器、分析、模拟......

因此对于您的具体情况,您的任务列表似乎是:

  • 创建一个能够通过蓝牙进行通信的BLEManager类。
  • 创建一个数据管理器类,该类将能够处理、处理和可能存储来自所需输入的数据,例如 BLEManager
  • 创建一个接口(interface)单例,其中包括核心所需的所有附件,例如 BLEManager 和数据管理器。单例应提供一个从使用角度来看有意义的公共(public)接口(interface),并包括委托(delegate)系统或通知系统。

界面应该是这样的:

标题

@protocol CoreManagerDelegate
- (void)coreManager:(CoreManager *)sender updatedData:(id)data;
@optional
- (void)coreManager:(CoreManager *)sender encounteredIssue:(NSError *)issue;

- (void)coreManager:(CoreManager *)sender changedConnectionState:(BluetoothConnectionState)isConnected; // BluetoothConnectionStateUnkown, BluetoothConnectionStateDisabled, BluetoothConnectionStateNotPaired, BluetoothConnectionStateConnected...
@end

@interface CoreManager : Singleton
@property (weak) id<CoreManagerDelegate> delegate;
- (void)initialize;

- (void)fetchBluetoothData;
- (id)getCurrentData;

@end

来源

@interface CoreManager()
@property BLEManager *bluetoothManager;
@property DataManager *dataManager;
@end

@implementation CoreManager
#pragma mark - Bluetooth manager attachment
- (void)fetchBluetoothData {
    [self.bluetoothManager fetchSomeData];
}
#pragma mark Delegate
- (void)BLEManager:(BLEManager *)sender receivedNewData:(id)data {
    // do data validation, log if needed, report...
    [self.dataManager insertNewData:data];
}
- (void)BLEManager:(BLEManager *)sender encounteredIssue:(NSError *)issue {
    // modify and evaluate the error if needed
    if([self.delegate respondsToSelector:@selector(coreManager:encounteredIssue:)]) {
        [self.delegate coreManager:self encounteredIssue:issue];
    }
    else {
        // log error ?
    }
    // send the error to a remote service
}
#pragma mark - Data manager attachment
- (id)getCurrentData {
    return [self.dataManager currentData];
}
#pragma mark Delegate
- (void)dataManager:(DataManager *)sender updatedData:(id)processedData {
    [self.delegate coreManager:self updatedData:processedData];
}
- (void)dataManager:(BLEManager *)sender encounteredIssue:(NSError *)issue {
    // modify and evaluate the error if needed
    if([self.delegate respondsToSelector:@selector(coreManager:encounteredIssue:)]) {
        [self.delegate coreManager:self encounteredIssue:issue];
    }
    else {
        // log error ?
    }
    // send the error to a remote service
}
@end

这将维护一个非常干净和敏捷的代码。它将防止任何不必要的类或文件膨胀。它为测试和模拟数据提供了一个非常好的机会。从使用角度来看,添加附加功能将是透明的:例如,实现核心数据不会对项目的用户界面部分产生任何更改。

id 类型应该尽可能替换为具体的自定义对象。即使是错误和日志也最好是自定义的,这样您就可以轻松地在整个应用程序中跟踪它们,随意启用和禁用它们。

注意:如果您认为此时将您的蓝牙管理器转换为普通对象而不是单例的更改太大,您可能仍将其保持为单例并简单地覆盖 getter 以返回共享实例。

我相信还有很多其他好的做法,但这是我最常使用的,并且已被证明是迄今为止最好的。希望对您有所帮助。

关于ios - 我应该如何构建我的应用程序来处理传入的蓝牙数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30085122/

相关文章:

iphone - 将 NIB 文件加载到 UIView 时遇到问题

bluetooth - 更改树莓派蓝牙设备名称?

ios - 这个散列保证是唯一的吗?

iphone - 在图像上创建一个图层并通过触摸调整其坐标

ios - 快速更改 UISlider 的高度

iphone - 如何使用 Game Center 仅使用 wifi 玩游戏?

android - 如何解决Android中发生的BluetoothGatt : android. os.DeadObjectException错误?

android - 蓝牙接收器响应时间

ios - 如何使用callkit 框架在iOS 原生ui 调用中显示来电图像?

ios - 如何在 objective-c 中从 int 切换到 string?