2019年5月23日 星期四

iOS swift 5: 關於兩個時間之間的時間差

關於兩個時間之間的時間差

解決方案來源:
swift 对日期的处理大全


 var Date1: Date = Date()
 var Date2: Date = Date()
 let nInterval = Date2.timeIntervalSince(Date1)

macOS: 超注音

原有 MacOS上的注音輸入法太難用 都亂猜字
這個輸入法現在用的還算不錯
試用版 30天
每次重新開機後, 第一次切換到中文輸入, 常常會失效
請用滑鼠點一下去切換,
切換成功後,未重新開機前, 使用上都滿順的.

產品: 超注音 for macOS
不限制 MacOS 電腦數量, 但只能用在MacOS不可用在 iPhone, iPad
下載: 超注音 for macOS Ver 1.0.6

購買用於 MacOS電腦
費用: NT$500元


小麥注音輸入法是一套免費macOS專用輸入法
有多種注音的鍵盤配置模式
McBopomofo 小麥注音輸入法

另外還有一套多種平台的免費輸入法
但注音的鍵盤配置只有傳統排列方式
  中州韻輸入法引擎


2019年5月22日 星期三

iOS swift 5: 關於 "UIAlertController actionSheet Exception"


解決方案來源:
1: 顯示警告訊息和選單的 UIAlertControlle
2: Swift 4 Tutorial : Show PopOver with TableView from Scratch (Source file link in 
description)
3: ActionSheet Popover on iPad in Swift

 *** Terminating app due to uncaught exception
 'NSGenericException', reason: 'Your application has presented a
  UIAlertController (<UIAlertController: 0x1160ef600>) of
   style UIAlertControllerStyleActionSheet from XXX.MainViewController (<XXX.MainViewController: 0x116036600>).
   The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide
   location information for this popover through the alert controller's popoverPresentationController. You must provide
   either a sourceView and sourceRect or a barButtonItem.  If this information is not known when you present the alert

   controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'

意思就是沒有設置UIAlertController這個彈出窗口的位置信息



 @IBAction func BtnTestOnClick(_ sender: Any)
 {
    
  let alertController = UIAlertController(title: nil, message: "Alert message.", preferredStyle: .actionSheet)

  let defaultAction = UIAlertAction(title: "Default", style: .default, handler: { (alert: UIAlertAction!) -> Void in
    //  Do some action here.
  })

  let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { (alert: UIAlertAction!) -> Void in
    //  Do some destructive action here.
  })

  let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { (alert: UIAlertAction!) -> Void in
    //  Do something here upon cancellation.
  })

  alertController.addAction(defaultAction)
  alertController.addAction(deleteAction)
  alertController.addAction(cancelAction)
  
  if let popoverController = alertController.popoverPresentationController {
   popoverController.sourceView = self.view
   popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
   popoverController.permittedArrowDirections = []
  }

  self.present(alertController, animated: true, completion: nil)
 }

iOS swift 5: 關於 "CoreBluetooth XPC connection invalid"

CBCentralManager 這個class, 真的很不容易使用,限制滿多的.

解決方案來源:
ShenYun's Memo: iOS CoreBluetooth swift 2 連線客製化藍芽 BLE 模組 - ( 2 ) 連線
swift - CoreBluetooth XPC connection invalid - Stack Overflow


解說
 1: 專案的 Target -> Capabilities -> Background Modes -> 勾選兩個 Bluetooth LE Accessor

 2: info.plist 要加上
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Play with BLE Compatible devices</string>

 3: 把 CBCentralManager 放在一個 Class中

class TBleDeviceConnect: NSObject, CBCentralManagerDelegate, BPeripheralDelegate
{
   var centralManager: CBCentralManager! = nil
   func centralManagerInit()
   {
    centralManager = CBCentralManager.init(delegate: self, queue: nil, options: [CBCentralManagerOptionShowPowerAlertKey: true])
   }
}

 4: 把包含 CBCentralManager Class放到 MainViewController 中
     CBCentralManager一定要在 UIViewController
class MainViewController: UIViewController
{
   /* Class Bluetooth CBCentralManager Control */
   var BleDeviceConnect: TBleDeviceConnect! = nil
}

 5: 如果是用在其他的 ViewController
    用 prepare for segue 方法將 CBCentralManager傳遞過去
    請參考 iOS swift 5: About Segue Prepare to NavigationController 

 6: 如果是在 Thread Function 中使用
DispatchQueue.main.async
{
 self.BleDeviceConnect.centralManagerInit()  
}

 7: 同一個Class 中的CBCentralManager 只能呼叫一次 centralManager = CBCentralManager.init(...)
   就會發生 "CoreBluetooth XPC connection invalid"
   解決方法還在尋找中....
   所以現在的做法呼叫 scanForPeripherals來重新掃描 Bluetooth Device











iOS swift 5: 關於 Segue Prepare to NavigationController


解決方案來源:
ios - Swift : prepareForSegue with navigation controller - Stack Overflow

class MainViewController: UIViewController
{
   /* Class Bluetooth CBCentralManager Control */
   var BleConnectDevice: TBleDeviceConnect! = nil
    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
     if( segue.identifier == "SegueOptions")
     {
      let destinationNavigationController = segue.destination as! UINavigationController
      let OptionsVc = destinationNavigationController.topViewController as! OptionsTableViewController
      OptionsVc.BleScannerDevice = self.BleScannerDevice
     }
    }
}

class OptionsTableViewController: UITableViewController, UITextFieldDelegate
{
    var BleScannerDevice: TBlueScannerDevice! = nil
    @IBAction func BtnBleOnClick(_ sender: Any)
    {
      DispatchQueue.main.async
      {
       self.BleScannerDevice.CentralManagerInit()
      }
    }
}

class TBleDeviceConnect: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate
{
    var cCentralManager: CBCentralManager! = nil
    func CentralManagerInit()
    {
     cCentralManager = CBCentralManager.init(delegate: self, queue: nil, options: [CBCentralManagerOptionShowPowerAlertKey: true])
    }
}