2023年10月5日 星期四

XCODE & SWIFT & BLE

家裡老舊的蘋果mini 2012 late版本只能更新到10.13,無法使用XCODE。使用M1(13.6)下載XCODE版本15.0。

XCODE是IDE,對比於EClipse和Android Studio。基本操作語言為swift(類比於JAVA或Kotlin)。專案分成兩種,可開新專案,TAB選擇IOS,下面跳出Application和LIB兩大類,選擇Application類的第一項APP(連結)。
  • Product Name : HelloWorld
  • Team : skip
  • Organization : com.xxx
  • Bundle Identifier : 送審使用,先不用管
  • Interface : Storyboard,Xcode支援兩種 UI 建構方式Storyboard和SwiftUI
  • Language : Swift,Xcode支援 Objective-C 與 Swift
  • Use Core Data : 資料庫先不管
  • Include Tests : 測試先不管
或是開啟舊專案。如下載github的zip解壓縮,範例(連結)。對於從零開始寫IOS程式很有用(GITHUUB)。副檔名是xcodeproj。功能是按鈕直接傳送資料,收到回應後顯示在TEXTBOX內。

畫面

最基本的StoryBoard,UI入口為Main(介面編輯器)。點選右上方的加號,跳出元件選單。選擇Button拉到白色畫面中間,預設的名稱是Button,從右邊選單更改名稱為Hello World。右側選單還有非常多更新介面例如顏色等等的功能。

按鈕按下後,會帶動程式,程式在哪裡呢?因為APP模板預設有View對應架構,只要將動作直接放進View中即可。
    @IBAction func showMessage(sender: UIButton) {
        let alertController = UIAlertController(title: "Welcome to My First App", message: "Hello World", preferredStyle: UIAlertController.Style.alert)
        alertController.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
        present(alertController, animated: true, completion: nil)
    }

連結方式很"抽象",以外接滑鼠為例,回到Main畫面,點選button,按住右鍵就會拉出直線,將直線拖拉到(按鈕仍然維持在原本位置上)畫面上方有三個按鈕的最左邊,也就是viewcontroller上。放開右邊按鈕,就會跳出viewcontroller中可以連結的function。例如剛剛的showmessagexxxx。完成。
storyboard使用就是uikit,更多操作說明連結
對應這幾年推出更新的開發方案稱為swiftUI連結


MVC架構

基礎包括SWIFT的語法(連結

Basic Chat是MVC架構(藍芽的部分紀錄在另外一篇),無論是Android或是XCode都大量運用MVC,也算是軟體工程的一大進步吧。
MODEL沒有內容
VIEW很簡單
CONTROL有兩個
    ConsoleViewController 負責與VIEW溝通
    包含在ViewController中

MAIN中有三個項目,這讓我想到,如何在MAIN中增加VIEW(連結)
NAVIGATION CONTROLLER(找不到)
VIEW CONTROLLER
CONSOLE VIEW CONTROLLER

IDE編輯技巧

使用tab會跳出可選擇項目
滑鼠點擊某個文字後,按下option,就會跳出這個物件能夠使用的項目

執行:模擬器

menu->product->run 或是右邊箭頭,就會開始執行,執行有幾種,若有裝模擬器就能往模擬器送,模擬器是要另外下載IOS模擬器(模擬器是否支援藍牙不確定)。當設定過一次後,會記住。模擬器本身是個單獨的application,這個概念在Android Studio是一樣的。
更改設定的位置連結
模擬器不具備藍芽功能

執行:DEBUG

程式中加入print("hello"),會在xcode的右下方出現hello。  連結

print("Function: \(#function),Line: \(#line)")
結果是 Function: centralManager(_:didDiscover:advertisementData:rssi:),Line: 169
print("Peripheral Discovered: \(peripheral)")
結果是 Peripheral Discovered: <CBPeripheral: 0x28353e630, identifier = DDBFB78C-8690-C039-877E-556D31A8DA1B, name = OneTouch J05D, mtu = 0, state = disconnected>



執行:實機

參考 連結。成功。


SWIFT:語法



SWIFT:畫面進階

連結.  背景是深色會有錯誤
連結  動畫功能,因為工作需要顯示進度

BLE

理論:介紹(連結 連結 連結)。

基本character:範例(連結)。完整範例(連結 GITHUUB)。尋找和管理BLE裝置。方式有二,最直覺是右上方文字啟動,比較特別是程式啟動畫面切到viewcontroller,因為viewcontroller有繼承CBCentralManagerDelegate,只要進入這個頁面就會開始啟動,若先前已經允許藍芽,當藍芽是啟動狀況就會執行startScanning。

  1. 找到空間中全部藍芽裝置 centralManager?.scanForPeripherals(withServices: nil , options: [CBCentralManagerScanOptionAllowDuplicatesKey:true])
  2. 列印出各個項目(可能上百個,會進入的下面function)func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { }
    在這個function print("Peripheral Discovered: \(peripheral)"). 結果是 Peripheral Discovered: <CBPeripheral: 0x28353e630, identifier = DDBFB78C-8690-C039-877E-556D31A8DA1B, name = OneTouch J05D, mtu = 0, state = disconnected>
    有時候會重複,但沒有關係。RSSI : 訊號強弱  Advertisement : BLE 裝置透過 Advertising 告知周邊 BLE 裝置自己的存在,其中, 考慮到 WiFi 的干擾,Advertising 封包在以下 3 個 bluetooth channel 上廣播:channel 37 (2402 MHz), channel 38 (2426 MHz), 和 channel 39 (2480 MHz)
  3. 連線 centralManager.connect(peripheral, options: nil)  //參數很多,不用理會( 連結 )。連線後,有兩種反應,一種是成功,一種是失敗。
    centralManager(CBCentralManager, didConnect: CBPeripheral)
    centralManager(CBCentralManager, didFailToConnect: CBPeripheral, error: Error?)
    實驗結果是onetouch無法connect,下載了appstore軟體也沒有辦法連結,因此有點病急亂投醫,胡亂搞。但原相可以往下走,暫時歸因於硬體因素?
  4. Service。連結
    stopscan
    peripheral.delegate = self
    peripheral.discoverServices(nil)
    func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?)
    print(“Found \(services.count) services! :\(services)”)
    對每個services可以取得數字確認是否符合,並且繼續詢問後續characteristic,確認符合Service和Characteristic。另外一種做法是,scan的時候就直接填入service號碼,只有符合號碼才會顯示出來。
  5. Characteristic
    func peripheral(peripheral: CBPeripheral,didDiscoverCharacteristicsForService service: CBService,error: NSError?)
    peripheral.readValueForCharacteristic(characteristic)
    func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?)
    print(“characteristic uuid: \(characteristic.UUID), value: \(characteristic.value)”)
    if characteristic.uuid.isEqual(CBUUIDs.BLE_Characteristic_uuid_Rx)  {
    rxCharacteristic = characteristic
    BlePeripheral.connectedRXChar = rxCharacteristic
    peripheral.setNotifyValue(true, for: rxCharacteristic!)
    peripheral.readValue(for: characteristic)
    print("RX Characteristic: \(rxCharacteristic.uuid)")
    }
    if characteristic.uuid.isEqual(CBUUIDs.BLE_Characteristic_uuid_Tx)
    {
    txCharacteristic = characteristic
    BlePeripheral.connectedTXChar = txCharacteristic
    print("TX Characteristic: \(txCharacteristic.uuid)")
    }
  6. Bonding,這步驟完成才算是pairing完成。裝置列表會在table中,點選其中一個就會connectToDevice。也就是後續寫入和讀取資料。
  7. 寫入資料
    peripheral.writeValue(data, forCharacteristic: characteristic, type: CBCharacteristicWriteType.WithResponse)
    func peripheral(peripheral: CBPeripheral,didWriteValueForCharacteristic characteristic: CBCharacteristic,error: NSError?)
    print(“Succeeded!”)
    writeValueForCharacteristic的方法將值寫入characteristic
    CBCharacteristicWriteWithResponse   CBPeripheralDelegate didwriteValueFor
    CBCharacteristicWriteWithoutResponse    不能使用上面方法判斷
  8. 讀出資料
  9. 斷線didDisconnectPeripheral

沒有留言:

張貼留言