2024-11-25

iOS-OTA版本說明

OTASDKDemo的目的是做最簡單的OTA集成Demo程序吟温,讓開發(fā)者能以最小的成本實(shí)現(xiàn)對我司OTASDK的整合绞灼。

請將Xcode版本升級到Xcode14以上姿骏。否則會出現(xiàn)找不到符號的錯(cuò)誤。

SLB OTA參考的網(wǎng)址https://www.aligenie.com/doc/357554/iz1ttl

20220628更新1.1.1版本

1尺借、支持多設(shè)備OTA顶岸,同一時(shí)間可以并行6個(gè)設(shè)備進(jìn)行數(shù)據(jù)傳輸

2、優(yōu)化使用體驗(yàn)芍阎,不再需要選擇模式世曾,會根據(jù)設(shè)備服務(wù)特性自動進(jìn)行判斷

3、優(yōu)化升級成功率

4谴咸、優(yōu)化錯(cuò)誤碼

5轮听、簡化SDK開發(fā)流程

按如下流程進(jìn)行處理:

  • initOTA
  • startScan
  • selectFilePath
  • addDevices
  • tryStartOTA

App Store 1.1.2版本 針對重復(fù)升級模式,進(jìn)行優(yōu)化岭佳,沒有涉及SDK上的修改

20220801 SDK 更新1.1.3版本 針對App已經(jīng)連接設(shè)備的情況下血巍,集成我司SDK,在不斷開的情況下珊随,直接傳遞藍(lán)牙對象進(jìn)行OTA述寡。對手環(huán)項(xiàng)目,這是非常必要的優(yōu)化叶洞。

奉加OTA開發(fā)文檔

一鲫凶、如何使用OTASDK.xcframework

1、導(dǎo)入頭文件

#import <OTASDK/OTASDK.h>

2衩辟、初始化藍(lán)牙中心管理器螟炫,一定要設(shè)置委托協(xié)議PHYBLEManagerDelegate。

self.bluetoothManager = [PHYBLEManager shareInstance];
self.bluetoothManager.delegate = self;

3艺晴、監(jiān)聽設(shè)備藍(lán)牙開啟或關(guān)閉

- (void)centerMessage:(NSString *)message code:(NSUInteger)code {
    
    if (code == BLENOTActive) {
        NSLog(@"%@",message);
        [self stopScanAction];
    }else if(code == BLEActive) {
        [self startScanAction];
    }
    
}

4昼钻、掃描設(shè)備。會將未設(shè)備藍(lán)牙名的設(shè)備過濾掉财饥,在開啟掃描前换吧,先判斷是否已經(jīng)在掃描中,避免重復(fù)掃描钥星,節(jié)約資源沾瓦。

if (!self.bluetoothManager.isScanning) {
   [self.bluetoothManager startScan];
}

掃描結(jié)果回調(diào):

- (void)deviceFound:(NSArray *)devicesArray {
    
    self.showArray = [devicesArray mutableCopy];
    [self.tableView reloadData];
    
}

5、停止掃描

if (self.bluetoothManager.isScanning) {
    [self.bluetoothManager stopScan];
}

6谦炒、選擇需要升級的設(shè)備贯莺,以數(shù)組形式設(shè)置。

[self.bluetoothManager addDevices:self.selectArray];

7宁改、為設(shè)備選擇升級文件缕探,這個(gè)方法應(yīng)該在添加設(shè)備之前。

[self.bluetoothManager selectFilePath:fileModel.fileAbsolutePath];

8还蹲、開始升級

[self.bluetoothManager tryStartOTA];

9爹耗、清空設(shè)備列表和文件數(shù)據(jù)耙考,意味著OTA升級環(huán)境變量初始化,重新開始OTA前最好是執(zhí)行這個(gè)方法重置一次潭兽。

[self.bluetoothManager initOTA];

10倦始、進(jìn)度信息,升級完成山卦,升級異常等等鞋邑,均通過如下回調(diào)

- (void)listenNotify:(CBPeripheral *)peripheral message:(NSString *)message code:(NSUInteger)code {
    self.selectArray = [self.bluetoothManager.deviceArray mutableCopy];
    
    [self.tableView reloadData];
}

iOS OTA代碼詳解

1、AppDelegate

合并項(xiàng)目時(shí)用不到账蓉。如下代碼是其他文件打開接收升級文件枚碗,將升級文件從微信,QQ铸本,釘釘?shù)韧ㄐ臕pp下載后存入iOS App儲存空間肮雨。

#pragma mark - ApplicationDelegate
- (BOOL)application:(UIApplication *)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options {
    if (options) {
        NSString *str = [NSString stringWithFormat:@"\n發(fā)送請求的應(yīng)用程序的 Bundle ID:%@\n\n文件的NSURL:%@", options[UIApplicationOpenURLOptionsSourceApplicationKey], url];
        NSLog(@"%@", str);
        
        if (self.window && url) {
            // 根據(jù)“其他應(yīng)用” 用“本應(yīng)用”打開,通過url归敬,進(jìn)入列表頁
            [self pushDocListViewControllerWithUrl:url];
        }
    }
    return YES;
}

#pragma mark ApplicationDelegate Method
/** 根據(jù)“其他應(yīng)用” 用“本應(yīng)用”打開酷含,通過url,進(jìn)入列表頁 */
- (void)pushDocListViewControllerWithUrl:(NSURL *)url {

}

2汪茧、SelectDeviceVC

實(shí)現(xiàn)掃描周邊藍(lán)牙設(shè)備椅亚,選擇待升級設(shè)備的功能。

主要涉及如下代碼

2.1舱污、藍(lán)牙初始化和設(shè)置委托

//藍(lán)牙初始化
  self.bluetoothManager = [PHYBLEManager shareInstance];
  self.bluetoothManager.delegate = self;

執(zhí)行self.bluetoothManager.delegate = self;時(shí)會將藍(lán)牙中心回調(diào)指向OTASDK呀舔。

2.2、將OTA狀態(tài)初始化

一般客戶工程師無需進(jìn)行這步扩灯,在SDK內(nèi)部媚赖,每一次新的OTA開始時(shí)會自動執(zhí)行。

[self.bluetoothManager initOTA];

SDK內(nèi)部實(shí)現(xiàn)如下:

- (void)initOTA {
    [self.deviceArray removeAllObjects];
    myFilePath = nil;
    fileDetail = nil;
    isStartOTA = NO;
    mtusize = 0;
}

2.3珠插、開始掃描設(shè)備

[self startScanAction];

掃描結(jié)果會在deviceFound回調(diào)方法中返回惧磺。返回結(jié)果是過濾掉空藍(lán)牙名,根據(jù)信號強(qiáng)度排序的所有設(shè)備的數(shù)組捻撑。

- (void)deviceFound:(NSArray *)devicesArray

2.4磨隘、SDK對藍(lán)牙是否開啟的檢測

如果檢測到手機(jī)藍(lán)牙已關(guān)閉,會通過如下回調(diào)中返回顾患。這個(gè)部分一般用不到番捂,客戶工程師都會在項(xiàng)目啟動時(shí)就進(jìn)行檢測。

可以參考代碼中關(guān)于OTAType枚舉值的使用方式

- (void)centerMessage:(NSString *)message code:(NSUInteger)code {
    self.showTip.text = message;
    if (code == BLENOTActive) {
        NSLog(@"%@",message);
        [self stopScanAction];
    }else if(code == BLEActive) {
        [self startScanAction];
    }else {
        [self showAlert:message];
    }
}

2.5江解、掃描時(shí)不會觸發(fā)具體藍(lán)牙設(shè)備的回調(diào)

為了兼容Swift设预,3個(gè)委托方法必須實(shí)現(xiàn),但在掃描期間如下回調(diào)方法不會用到

- (void)listenNotify:(CBPeripheral *)peripheral message:(NSString *)message code:(NSUInteger)code {
    NSLog(@"%@ -- %@",peripheral.name, message);
}

2.6犁河、將選擇的設(shè)備傳到SDK

使用如下語句將選擇的設(shè)備傳到SDK鳖枕。至少選擇一個(gè)設(shè)備魄梯。

 [self.bluetoothManager addDevices:self.selectArray];

在執(zhí)行上述語句前,請確認(rèn)2.1中的委托已經(jīng)設(shè)置宾符。因?yàn)樵趫?zhí)行上述語句后画恰,會自動連接數(shù)組中的第一個(gè)設(shè)備。如果沒有設(shè)置委托吸奴,將接收不到相關(guān)的回調(diào)的信息。

3.OTAUpgradeVC

實(shí)現(xiàn)每個(gè)藍(lán)牙設(shè)備的連接狀態(tài)缠局,傳輸升級文件進(jìn)度则奥,正常或異常情況等狭园。SDK中支持同時(shí)對6個(gè)進(jìn)行升級读处。

3.1、藍(lán)牙初始化和設(shè)置委托

如果客戶項(xiàng)目中有多類調(diào)用了BLEManager唱矛,則需要自己控制想讓哪個(gè)VC接收delegate的回調(diào)方法罚舱。

 self.bluetoothManager = [PHYBLEManager shareInstance];
 self.bluetoothManager.delegate = self;

3.2、獲取SDK中待升級設(shè)備

self.selectArray = [self.bluetoothManager.deviceArray mutableCopy];

待升級數(shù)組中的元素為PHYBLEModel對象绎谦,具體的定義如下:

@interface PHYBLEModel : NSObject

@property (nonatomic, strong) CBPeripheral *peripheral;   //系統(tǒng)藍(lán)牙對象
@property (nonatomic, strong) NSDictionary *advertisementData;//廣播數(shù)據(jù)
@property (nonatomic, strong) NSNumber     *RSSI;                   //信號強(qiáng)度
@property (nonatomic, strong) NSString     *realName;    //設(shè)備名稱
@property (nonatomic, strong) NSString     *adverMacAddr; //MAC地址
@property (nonatomic, strong) NSDate       *lastUpdateDate; //最后一次掃描時(shí)間

@property (nonatomic, assign) NSInteger    OTAType;      //OTA類型:SLB或者SingleBank
@property (nonatomic, strong) NSString     *OTAMessage;  //顯示的提示信息
@property (nonatomic, assign) int          disconnectTimes; //斷開連接次數(shù)

@property (nonatomic, strong) SLBContext   *mSLBContext;  //SLB模式傳輸數(shù)據(jù)中的參數(shù)
@property (nonatomic, strong) SBHContext   *mSBHContext;  //SBH模式傳輸數(shù)據(jù)中的參數(shù)
@property (nonatomic, strong, nullable) NSTimer      *myTimer; //定時(shí)器
@property (nonatomic, strong) NSMutableArray *bufferArray;   //一組數(shù)據(jù)的緩存

@end

可以根據(jù)待升級設(shè)備數(shù)組中元素的參數(shù)自行判斷設(shè)備的詳細(xì)狀態(tài)管闷。

3.3、升級模式:單次模式和循環(huán)模式

循環(huán)模式是為了壓測OTA的穩(wěn)定性窃肠,一般開發(fā)者不用管包个,代碼合并時(shí)也不要理會。

3.4冤留、加密OTA:Security OTA模式

Security OTA目前只在SBH模式下實(shí)現(xiàn)了碧囊,不支持SLB。僅支持hexe16格式的升級文件纤怒,使用的客戶較少糯而,客戶喜歡自研加密算法。

SLB加密OTA暫時(shí)沒有開發(fā)計(jì)劃泊窘。

如果不是加密模式熄驼,則項(xiàng)目中涉及到密鑰的代碼都可以不看。

3.5州既、總結(jié):自定義功能的實(shí)現(xiàn)方法

self.bluetoothManager.deviceArray的結(jié)果就是實(shí)時(shí)的SDK中待升級設(shè)備的狀態(tài)和各項(xiàng)參數(shù)谜洽。

第二種場景

假設(shè)項(xiàng)目中已經(jīng)連接藍(lán)牙設(shè)備,不想經(jīng)過斷開后再掃描吴叶、重連的耗時(shí)操作阐虚,如何進(jìn)行OTA?

這個(gè)場景下只支持單個(gè)設(shè)備OTA升級的情況。

專門針對這種場景蚌卤,基于第一個(gè)場景的代碼邏輯实束,改編出了如下解決方案奥秆。

4、DemoVC

這個(gè)模式需要開發(fā)者咸灿,根據(jù)自己設(shè)備名修改代碼构订。

打開App后,直接通過左上角的測試按鈕避矢,進(jìn)入到測試頁面悼瘾。

首先在demo程序源碼中,設(shè)置要升級設(shè)備的MAC地址或者UDID地址审胸,模擬設(shè)備已經(jīng)連接亥宿,然后修改項(xiàng)目中升級文件名稱。

4.1砂沛、藍(lán)牙初始化

假如客戶使用的是CBCentralManager烫扼,將系統(tǒng)藍(lán)牙的回調(diào)類指定為當(dāng)前類。同時(shí)進(jìn)行PHYBLEManager的初始化碍庵,但不要設(shè)置委托映企。

self.mCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
self.bluetoothManager = [PHYBLEManager shareInstance];

4.2、模擬設(shè)備已連接

模擬客戶App中啟動App立即連接設(shè)備的操作静浴。

在Demo頁面中按下開始按鈕進(jìn)行掃描堰氓,這里提供了兩種方式,可以根據(jù)MAC地址或藍(lán)牙名稱苹享,或者您可以自己根據(jù)廣播信息及UUID等其他方式建立連接豆赏。

進(jìn)入到DemoVC頁面,打開藍(lán)牙就會開始掃描富稻,建立連接掷邦,發(fā)現(xiàn)服務(wù)和特性。

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    
    NSObject *value = [advertisementData objectForKey:@"kCBAdvDataManufacturerData"];
    self.macString = [JCDataConvert getPeripheralMac:value];
    self.mPeripheral = peripheral;
    if ([self.macString isEqualToString:@"A2:62:22:00:00:19"] ||
        [peripheral.name isEqualToString:@"BUMBLE- -22000019"]) {
        [self.mCentralManager stopScan];
        NSLog(@"找到設(shè)備,進(jìn)行連接椭赋!%@",self.mPeripheral);
        [self.mCentralManager connectPeripheral:self.mPeripheral options:nil];
    }else if(peripheral.name.length > 0){
        NSLog(@"%@",peripheral.name);
    }
    
}

4.3抚岗、已連接單個(gè)設(shè)備OTA

需要修改升級文件名。Demo

在設(shè)備已經(jīng)連接的前提下哪怔,點(diǎn)擊DemoVC頁面中的開始按鈕宣蔚,執(zhí)行如下代碼,等待升級成功即可认境。

self.bluetoothManager.myCentralManager = _mCentralManager;

self.bluetoothManager.delegate = self;

//-----------  升級文件獲取的方式  -------------
NSString *folderPath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/Inbox/"]];
NSString *fileName = @"simpleBlePeripheral(1)_phy6222.hex16";
NSString *FileURL = [folderPath stringByAppendingPathComponent:fileName];
[self.bluetoothManager selectFilePath:FileURL];

[self.bluetoothManager connectedDeviceOTA:self.mPeripheral mac:self.macString];
  • 我們知道手機(jī)中只有一個(gè)藍(lán)牙胚委,所以這里采用將DemoVC中的藍(lán)牙管理對象CBCentralManager傳遞到SDK中。傳遞之后接收不到CBCentralManager的委托方法叉信,相當(dāng)于藍(lán)牙訪問權(quán)限交給了OTASDK亩冬。
  • 接收來自O(shè)TASDK的回調(diào)方法,設(shè)置OTASDK的委托為當(dāng)前類。
  • 設(shè)置升級文件硅急,可以寫死的項(xiàng)目中或者通過服務(wù)器下載覆享。
  • 將要升級的設(shè)備傳遞到SDK中。SLB模式下MAC地址可以填空字符串@“”营袜。

4.4撒顿、OTASDK回調(diào)方法

以獲取自定義進(jìn)度條的值作為例子,代碼如下:

- (void)listenNotify:(CBPeripheral *)peripheral message:(NSString *)message code:(NSUInteger)code {
    self.showLabel.text = message;
    if(code == ProgressCallBack) {
        float value = [message floatValue];
        NSLog(@"Custom progress value: %.2f",value);
    }
}

另外:OTASDK中目前已經(jīng)支持的事件

typedef NS_ENUM(NSInteger, OTAType) {
    None = 0,
    /*藍(lán)牙狀態(tài)*/
    BLENOTActive,           //未檢測到藍(lán)牙開啟!
    BLEActive,              //成功檢測到藍(lán)牙開啟!
    LastTaskNotEnd,         //上次升級任務(wù)還未完成荚板!
    UnexpectedConnection,   //存在意料之外的BLE連接凤壁!
    ChangeFileFail,         //升級途中不能修改OTA文件!
    UnbelievableError,      //理論上不會觸發(fā)的錯(cuò)誤跪另!
    OTAEnd,                 //本輪OTA結(jié)束
    RESCANStart,            //二次掃描開始
    RESCANDevice,           //二次掃描找到設(shè)備

    DeviceConnecting,       //連接中...
    DeviceConnectFail,      //設(shè)備建立連接失斂驮!
    DeviceDisconnected,     //設(shè)備連接已經(jīng)斷開罚斗!
    
    ServicesDiscovering,    //連接成功,發(fā)現(xiàn)服務(wù)中...
    SLBServiceFound,        //SLB服務(wù)獲取成功宅楞!發(fā)現(xiàn)特性中针姿!
    SBHServiceFound,        //SBH服務(wù)獲取成功,發(fā)現(xiàn)特性中!
    
    SLBOTAConfirm,          //特性確認(rèn),SLB升級模式厌衙!
    SBHAppConfirm,          //特性確認(rèn),SBH App模式距淫!
    SBHOTAConfirm,          //特性確認(rèn),SBH OTA模式!
    
    SBHAppSecurity,         //安全模式下指令傳輸
    SLBDeviceReady,         //特性Enable成功婶希,SLB設(shè)備已準(zhǔn)備好榕暇!
    SBHOTADeviceReady,      //特性Enable成功,SBH OTA已準(zhǔn)備好喻杈!
    
    ProgressCallBack,       //進(jìn)度值返回
    OTADataOver,            //數(shù)據(jù)發(fā)送完畢彤枢,確認(rèn)升級數(shù)據(jù)中...
    OTACheckFail,           //數(shù)據(jù)傳輸完成后,CRC校驗(yàn)失斖彩巍缴啡!
    
    OTAComplete = 99,       //升級成功,可以主動斷開或者超時(shí)斷開瓷们!
    
    // 尋找下一個(gè)設(shè)備時(shí)业栅,不需要再連接
    SBHAppOver = 100,       //SBH App模式結(jié)束,等待二次掃描
    
    // 無法進(jìn)行OTA的錯(cuò)誤類型
    OTAServiceNotFound,     //設(shè)備缺少OTA的藍(lán)牙服務(wù)谬晕!
    OTAServiceConfuse,      //同時(shí)存在兩種升級服務(wù)碘裕!
    CharacteristicError,    //特性異常!
    MTUConflict,            //不支持該設(shè)備:MTUSize不一致!
    MAXDisconnectedTime,    //達(dá)到最大連接異常斷開次數(shù)
    NOMACAddress,
    
};

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末攒钳,一起剝皮案震驚了整個(gè)濱河市帮孔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌不撑,老刑警劉巖你弦,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惊豺,死亡現(xiàn)場離奇詭異,居然都是意外死亡禽作,警方通過查閱死者的電腦和手機(jī)尸昧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旷偿,“玉大人烹俗,你說我怎么就攤上這事∑汲蹋” “怎么了幢妄?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長茫负。 經(jīng)常有香客問我蕉鸳,道長,這世上最難降的妖魔是什么忍法? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任潮尝,我火速辦了婚禮,結(jié)果婚禮上饿序,老公的妹妹穿的比我還像新娘勉失。我一直安慰自己,他們只是感情好原探,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布乱凿。 她就那樣靜靜地躺著,像睡著了一般咽弦。 火紅的嫁衣襯著肌膚如雪徒蟆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天型型,我揣著相機(jī)與錄音后专,去河邊找鬼。 笑死输莺,一個(gè)胖子當(dāng)著我的面吹牛戚哎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嫂用,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼型凳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嘱函?” 一聲冷哼從身側(cè)響起甘畅,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谚中,沒想到半個(gè)月后跟压,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鼓鲁,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拘哨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了此熬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甜刻。...
    茶點(diǎn)故事閱讀 40,865評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呻袭,死狀恐怖顿天,靈堂內(nèi)的尸體忽然破棺而出堂氯,到底是詐尸還是另有隱情,我是刑警寧澤牌废,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布咽白,位于F島的核電站,受9級特大地震影響鸟缕,放射性物質(zhì)發(fā)生泄漏晶框。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一懂从、第九天 我趴在偏房一處隱蔽的房頂上張望授段。 院中可真熱鬧,春花似錦莫绣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至咖祭,卻和暖如春掩宜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背么翰。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工牺汤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浩嫌。 一個(gè)月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓檐迟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親码耐。 傳聞我的和親對象是個(gè)殘疾皇子追迟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 本文目錄 1、藍(lán)牙介紹 2骚腥、iBeacon 3敦间、iOS 藍(lán)牙 4、中心模式的使用 5、外設(shè)模式的使用 6廓块、后臺運(yùn)行...
    xiaofu666閱讀 8,581評論 0 21
  • GATT(GenericAttribute Profile): GATT是一個(gè)在藍(lán)牙連接之上的發(fā)送和接收很短的數(shù)據(jù)...
    vxtarget閱讀 1,361評論 0 0
  • 一厢绝、練習(xí)自我關(guān)懷身體掃描 今天早上5:00醒來,照例還要睡一覺的带猴,想著做正念練習(xí)昔汉,以往在床上做容易睡著,起床選擇在...
    呂瑩_3271閱讀 96評論 0 4
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 29,418評論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,113評論 1 32