2021年5月30日 星期日

swift 5: Bluetooth Central and Peripheral

一般都是把 iPad或 iPhone 當成 Central端, 再對 Peripheral(Device)進行控制

反過來就得要使用 CBPeripheralManager

但是測了幾個CBPeripheralManager範例, 使用兩台iPad連線, GATT傳輸都不是很穩定.

Central端使用 LightBlue

解決來源

 What's New in Core Bluetooth

 Getting Started with Bluetooth Low Energy

 BTLE Central Peripheral Transfer

 Core Bluetooth snippets with Swift

 Creating iOS application as Bluetooth Peripheral

 BLEPeripheral (測試過, 很簡易的範例)

 The Ultimate Guide to Apple’s Core Bluetooth

 Bluetooth-LE-IOS-Swift (Peripheral Manager)


2021年5月27日 星期四

swift 5: 字串的 format 方法

 解決方案:

   Swift:字符串格式化 


範例:

  1. let string = "abc"
  2. print(String(format:"%@ ", arguments:[string]))

  3. let num = 10 print(String(format:"%4d", arguments:[num]))


2021年5月26日 星期三

swift 5: iPadOS textField 進入輸入模式(出現 keyboard) 畫面, 就會出現一堆錯誤訊息

 

類似下面這些一長串錯誤訊息

(
  "<NSAutoresizingMaskLayoutConstraint:0x281fe1b30 h=--& v=--& _UIButtonBarButton:0x1290c0cd0.height == 0  (active)>",
  "<NSLayoutConstraint:0x281ffa440 V:|-(6)-[_UIUCBKBSelectionBackground:0x1290c14c0]  (active, names: '|':_UIButtonBarButton:0x1290c0cd0 )>",
  "<NSLayoutConstraint:0x281ffa3a0 _UIUCBKBSelectionBackground:0x1290c14c0.bottom == _UIButtonBarButton:0x1290c0cd0.bottom - 6  (active)>"
)

解決來源:

Strange UIButtonBarButton layout errors on all textView, fields and searchbars on iPad only

解決方法:

// Workaround to remove autolayout errors when keyboard shows on iPad.
// <NSAutoresizingMaskLayoutConstraint:0x28376afd0 h=--& v=--& _UIButtonBarButton:0x107f0ce30.height == 0   (active)>
// Introduced approx iOS 14.2 according to https://developer.apple.com/forums/thread/667441
// Side effect: Removes the redo/undo and paste buttons from the keyboard
let item = textField.inputAssistantItem
item.leadingBarButtonGroups = []
item.trailingBarButtonGroups = []

2021年5月13日 星期四

Apple ID 雙重認證及電話號碼 被鎖

使用 Apple ID 進行雙重認證, 須要一個電話號碼,

但同一個電話號碼只能在約 30幾個ID 進行雙重認證,

(2021.12.10 實測驗證一個門號能雙重認證到 21個Apple ID)

(2023.01.18 實測驗證一個門號能雙重認證到 23個Apple ID)

(2023.07.20 實測驗證一個門號能雙重認證到 32個Apple ID)

超過後就會被鎖定, 從此這電話號碼就無法再用於其他Apple ID的認證.

把之前已認證Apple ID的電話移除或變更也沒有用,

也就是說 這個電話號碼廢了.

(2023.02.23 測試到一組曾被鎖定的號碼,可再增加認證Apple ID)

Apple 客服也無法解決, 某日和客服聊起這事, 隱隱地提示使用預付卡號碼.

(評估過後台灣大的預付卡最便宜)



如果需要設置大量的 Apple ID
可以評估 Apple Business Manager + JamF方案
(JamF是要另行付費)
相關資訊可以先洽詢 Apple Xinyi A13 Business Team
服務態度非常的好, 有問必答.







2021年1月11日 星期一

Ubuntu 20.04+PHP -資料存取(七) iOS swift Alamofire 5.2 POST

  本程式範例只適用於 Alamofire 5.2 

------------------------------------ 

參考來源:

 利用 Postman 來測試 Web Service 的工具

  https://franksios.medium.com/postman-測試web-service的工具-c7726997868a#.45rlrqve9

 Formatting JSON Data for Postman 

  https://stackoverflow.com/questions/38574039/formatting-json-data-for-postman

 Alamofire 

  https://github.com/Alamofire/Alamofire

 SwiftyJSON 

  https://github.com/SwiftyJSON/SwiftyJSON

 利用 Alamofire 處理 Http 請求 

  https://medium.com/allen的技術筆記/利用-alamofire-處理-http-請求-eb62f37118ca

 Alamofire學習(三)Request上篇 

  https://www.mdeditor.tw/pl/gaNU/zh-tw

------------------------------------ 

 Installation Alamofire

  CocoaPods

   pod 'Alamofire', '~> 5.2'

------------------------------------ 

建立檔案名稱: t7.php (內容同 t5,php)

並儲存到  https://www.mydomain.com/htdocs/t7.php


<?php

   $response = array();

   

   $data = json_decode(file_get_contents('php://input'), true);

   $item1 = $data["item1"];

   $item2 = $data["item2"];

   $item3 = $data["item3"];

   $item4 = $data["item4"];


   require_once ("config.php");

   $conn = mysqli_connect(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);

   if( !$conn) 

   {

    die("Connection failed: " . mysqli_connect_error());

   }

   else

   {

    $sql = "INSERT INTO mytabelname (name1, name2, name3, member) value ('$item1','$item2','$item3','$item4')";

    if (mysqli_query($conn, $sql)) 

    {

     $response['error']=false;

     $response['message']='mytabelname added successfully';

    }

    else 

    {

     echo "Error: " . $sql . "<br>" . mysqli_error($conn);

    }

    mysqli_close($conn);            

  }

  echo json_encode($response);

?>

------------------------------------

開啟 Postman 測試

. 選擇 POST

  輸入網址 https://www.mydomain.com/htdocs/t7.php

  Body 選擇 raw 和 JSON

  傳送資料填入下列

{

  "item1": "ABC",

  "item2": "DEF",

  "item3": "XYO",

  "item4": "356"

}

. 點選 Send



. 結果

  $postdata = file_get_contents("php://input", 'r');

  $jsondata = json_decode($postdata, true);

  $item1 = $jsondata["item1"];    

  使用上面三行 就可以取得傳入之資料 

   

------------------------------------

建立檔案名稱: t7.swift

iOS XCode 12.3 

import Foundation

import UIKit

func PhpJsonTest()

{

 let params: [String: Any] = ["item1": "ABC",

                              "item2": "DEF",

                              "item3": "HIJ",

                              "item4": "889"]

  AF.request( "https://www.mydomain.com/htdocs/t7.php", method: .post,  parameters: params, encoding: JSONEncoding.default)

   .validate()

   .responseData(emptyResponseCodes: [200, 204, 205]) { response in

   

    DPrint( response)

    switch response.result

    {

     case .success( let value):

       DPrint("Payment successful")

       if let responsedata = response.data, let str = String(data: responsedata, encoding: String.Encoding.utf8)

       {

        DPrint("FUNC: \(#file), \(#function), \(String(describing: str))")

       }

       let responseJSON = (try? JSONSerialization.jsonObject(with: value, options: []))

       if let responseJSON = responseJSON as? [String: Any]

       {

        DPrint(responseJSON)

        var msg : String!

        msg = responseJSON["message"] as! String?

        DPrint("FUNC: \(#file), \(#function), \(String(describing: msg))")

       }

       

     case .failure(let error):

       if (response.data?.count)! > 0

       {

        DPrint(error)

       }

       DPrint("Error Code: \(error._code)")

       DPrint("Error Messsage: \(error.localizedDescription)")

       if let data = response.data, let str = String(data: data, encoding: String.Encoding.utf8)

       {

        DPrint("Server Error: " + str)

       }

       DPrint("error processing the payment-> ", error.localizedDescription)

    }

   }

}

------------------------------------
建立檔案名稱: t71.swift
iOS XCode 12.3 使用 NSDictionary 

func PhpJsonTest()
{
 let params: [String: Any] = ["item1": "ABC",
                              "item2": "DEF",
                              "item3": "HIJ",
                              "item4": "889"]
  AF.request( "https://www.mydomain.com/htdocs/t7.php", method: .post,  parameters: params, encoding: JSONEncoding.default)
   .validate()
   .responseData(emptyResponseCodes: [200, 204, 205]) { response in
   
    DPrint( response)
    switch response.result
    {
     case .success( let value):
       DPrint("Payment successful")
       if let responsedata = response.data, let str = String(data: responsedata, encoding: String.Encoding.utf8)
       {
        DPrint("FUNC: \(#file), \(#function), \(String(describing: str))")
       }
       
       if let responseJson = (try? JSONSerialization.jsonObject(with: value, options: []))
       {
        let nsdresponse = responseJson as! NSDictionary
        let msg = nsdresponse.object(forKey: "message")!
        DPrint("FUNC: \(#file), \(#function), \(String(describing: msg))")
       }
       
     case .failure(let error):
       if (response.data?.count)! > 0
       {
        DPrint(error)
       }
       DPrint("Error Code: \(error._code)")
       DPrint("Error Messsage: \(error.localizedDescription)")
       if let data = response.data, let str = String(data: data, encoding: String.Encoding.utf8)
       {
        DPrint("Server Error: " + str)
       }
       DPrint("error processing the payment-> ", error.localizedDescription)
    }
   }
}

2021年1月7日 星期四

Ubuntu 20.04+PHP -資料存取(六) iOS+swift+MaraiaDB


參考來源:

 Swift3.0服務端開發(四) MySQL數據庫的連接與操作

  https://www.cnblogs.com/ludashi/p/6165418.html

 在Xcode裡面連線MySQL 

  https://www.itread01.com/content/1549641653.html

 PerfectlySoft/Perfect-MySQL 

  https://github.com/PerfectlySoft/Perfect-MySQL

  https://github.com/PerfectlySoft/Perfect/tree/master/Tests



待續...

Ubuntu 20.04+PHP -資料存取(五) POST+JSON+MaraiaDB

 


參考來源:

 Connecting iOS App to MySQL Database with Swift 5 Using Protocol Delegation and MVC Architectural Pattern

  https://medium.com/@joseortizcosta/connecting-ios-app-to-mysql-database-with-swift-5-using-protocol-delegation-and-mvc-architectural-259dc32fcc4b

 Swift: Uploading Data Securely to a MySQL Database 

  https://www.boomer.org/ios/sdb/

 The Best Way to Connect Your iOS App to MySQL Database (4 Steps)  

  https://codewithchris.com/iphone-app-connect-to-mysql-database/

 利用 Postman 來測試 Web Service 的工具

  https://franksios.medium.com/postman-測試web-service的工具-c7726997868a#.45rlrqve9

 Formatting JSON Data for Postman 

  https://stackoverflow.com/questions/38574039/formatting-json-data-for-postman


----------------------------------

建立檔案名稱: config.php 

並儲存到  https://www.mydomain.com/htdocs/config.php


 <?php

define('DB_USERNAME', 'root');

define('DB_PASSWORD', 'rootpasseprd');

define('DB_HOST', '192.168.1.X');

define('DB_NAME', 'mydbname');

?>

----------------------------------

開啟

 https://www.mydomain.com/phpmyadmin

建立一個資料庫, 名稱為  mydbname

-- Database : `mydbname`

CREATE DATABASE IF NOT EXISTS `mydbname`

  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

USE mydbname;

-- Privileges

GRANT SELECT, INSERT, DELETE, UPDATE, ALTER ON `mydbname`.* TO

    'root'@localhost;


在資料庫mydbname 中建立一個TABLE, 名稱為  mytabelname 

在TABLE mytabelname 中建立 5個欄位

-- Table structure for table `mytabelname`

CREATE TABLE IF NOT EXISTS `mytabelname` (

  `id` int(5) unsigned NOT NULL auto_increment,

  `item1` varchar(20) NOT NULL default '',

  `item2` varchar(20) NOT NULL default '',

  `item3` varchar(20) NOT NULL default '',

  `item4` int(10) unsigned NOT NULL,  

  PRIMARY KEY  (`id`),

)

 COMMENT='mytabelname Test'

 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

 

----------------------------------

建立檔案名稱: t5.php 

並儲存到  https://www.mydomain.com/htdocs/t5.php


<?php

   $response = array();

//   $jsondata = json_decode(file_get_contents('php://input'), true);

   $postdata = file_get_contents("php://input", 'r');

  var_dump($postdata); 

   $jsondata = json_decode($postdata, true);

  var_dump($jsondata); 

   $item1 = $jsondata["item1"];

   $item2 = $jsondata["item2"];

   $item3 = $jsondata["item3"];

   $item4 = $jsondata["item4"];


   require_once ("config.php");

   $conn = mysqli_connect(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);

   if( !$conn) 

   {

    die("Connection failed: " . mysqli_connect_error());

   }

   else

   {

    $sql = "INSERT INTO mytabelname (name1, name2, name3, member) value ('$item1','$item2','$item3','$item4')";

    if (mysqli_query($conn, $sql)) 

    {

     $response['error']=false;

     $response['message']='mytabelname added successfully';

    }

    else 

    {

     echo "Error: " . $sql . "<br>" . mysqli_error($conn);

    }

    mysqli_close($conn);            

  }

  echo json_encode($response);

?>

----------------------------------

建立檔案名稱: t5.swift

iOS XCode 12.3 

import Foundation

import UIKit

func PhpJsonTest()

{

 // created NSURL

  let urlString = URL(string: "https://www.mydomain.com/htdocs/t5.php")!

  var request = URLRequest(url: urlString)

 // setting the method to post

  request.httpMethod = "POST"

 // creating the post parameter by concatenating the keys and values from text field

 let json: [String: Any] = ["item1": "ABC",

                            "item2": "DEF",

                            "item3": "HIJ",

                            "item4": "567"]

 let jsonData = try? JSONSerialization.data(withJSONObject: json)

 // insert json data to the request

 request.httpBody = jsonData

 // creating a task to send the post request

 let task = URLSession.shared.dataTask(with: request)

 {

  data, response, error in

   guard let data = data, error == nil else {

    DPrint(error?.localizedDescription ?? "No data")

     return

   }

  // parsing the response

  do

  {

   let responseJSON = try JSONSerialization.jsonObject(with: data, options: [])

   if let responseJSON = responseJSON as? [String: Any]

   {

    DPrint(responseJSON)

    var msg : String!

    // getting the json response

    msg = responseJSON["message"] as! String?

    DPrint("\(#file), \(#function), \(String(describing: msg))")

   }

  }

  catch

  {

   DPrint(error)

  }

 }

 //executing the task

 task.resume()

}

----------------------------------

開啟 Postman 測試

. 選擇 POST

  輸入網址 https://www.mydomain.com/htdocs/t5.php

  Body 選擇 raw 和 JSON

  傳送資料填入下列

{

  "item1": "ABC",

  "item2": "DEF",

  "item3": "XYO",

  "item4": "356"

}

. 點選 Send

. 結果

  $postdata = file_get_contents("php://input", 'r');

  $jsondata = json_decode($postdata, true);

  $item1 = $jsondata["item1"];    

  使用上面三行 就可以取得傳入之資料  





Ubuntu 20.04+PHP -資料存取(四) POST+JSON+swift

參考來源:

Creating task for POST request to PHP script to add entries in MySQL database

 https://stackoverflow.com/questions/55990599/creating-task-for-post-request-to-php-script-to-add-entries-in-mysql-database

Receive JSON POST with PHP

 https://stackoverflow.com/questions/18866571/receive-json-post-with-php


 建立檔案名稱: t4.php 

並儲存到  https://www.mydomain.com/htdocs/t4.php

 <?php

   $response = array();

   

   $data = json_decode(file_get_contents('php://input'), true);

   $item1 = $data["item1"];

   $item2 = $data["item2"];

   $item3 = $data["item3"];

   $item4 = $data["item4"];

    

   $response['error']=false;

   $response['message']='item1 successfully';

  }

  echo json_encode($response);

?>


建立檔案名稱: t4.swift

iOS XCode 12.3 


import Foundation

import UIKit

func PhpJsonTest()

{

 // created NSURL

  let urlString = URL(string: "https://www.mydomain.com/htdocs/t4.php")!

  var request = URLRequest(url: urlString)


 // setting the method to post

  request.httpMethod = "POST"

        

 // creating the post parameter by concatenating the keys and values from text field

 let json: [String: Any] = ["item1": "ABC",

                            "item2": "DEF",

                            "item3": "HIJ",

                            "item4": "567"]

 let jsonData = try? JSONSerialization.data(withJSONObject: json)

 // insert json data to the request

 request.httpBody = jsonData


 // creating a task to send the post request

 let task = URLSession.shared.dataTask(with: request)

 {

  data, response, error in

   guard let data = data, error == nil else {

    DPrint(error?.localizedDescription ?? "No data")

     return

   }

  // parsing the response

  do

  {

   let responseJSON = try JSONSerialization.jsonObject(with: data, options: [])

   if let responseJSON = responseJSON as? [String: Any]

   {

    DPrint(responseJSON)

    var msg : String!

    // getting the json response

    msg = responseJSON["message"] as! String?

    DPrint("FUNC: \(#file), \(#function), \(String(describing: msg))")

   }

  }

  catch

  {

   DPrint(error)

  }

 }

 //executing the task

 task.resume()

}

Ubuntu 20.04+PHP -資料存取(三) POST

參考來源:

 Postman - 測試 API 神器 1/2

  https://ithelp.ithome.com.tw/articles/10201503



 建立檔案名稱: t3.php 

並儲存到  https://www.mydomain.com/htdocs/t3.php

<?php

header('Content-Type: text/html;charset=UTF-8');

$post=$_POST["item1"];

echo "POST=".$post;

?>


建立檔案名稱: t3.html

並儲存到  https://www.mydomain.com/htdocs/t3.html

<!DOCTYPE html>

<head>

  <meta charset="utf-8">

  <title>PHP Test</title>

</head>

<body>

  <form method="post" action="t3.php" name="form1">

    <input type="text" name="item1" value="">

    <input type="submit" value="確定" name="ok"> 

  </form>

</body>

</html>



測試時請注意是用 t3.html 還是 t3.php 
開啟 Chrome 
. 輸入網址 https://www.mydomain.com/htdocs/t3.html
  在欄位中輸入一些文字 234, 
  點選確定



. 輸入網址 https://www.mydomain.com/htdocs/t3.php?item1=abc
   因為是POST 所以不可這樣使用

. 開啟 Postman 
. 選擇 POST
  輸入網址 https://www.mydomain.com/htdocs/t3.php
  Body 選擇 x-www-form-urlencoded
  key 輸入  item1   
  value輸入 abc
  點選 Send











Ubuntu 20.04 + PHP -資料存取(一) _REQUEST

 參考來源:

 PHP 的 $_GET, $_POST, 與 $_REQUEST 測試

  http://yhhuang1966.blogspot.com/2015/05/php-get-post-request.html

 Postman - 測試 API 神器 1/2

  https://ithelp.ithome.com.tw/articles/10201503

 Postman - 測試 API 神器 2/2 

  https://ithelp.ithome.com.tw/articles/10201528

使開發API更方便的工具 Postman (基本教學)

  https://xenby.com/b/151-推薦-使開發api更方便的工具-postman


 

在 /var/www/html 目錄下建立一個 php的目錄

將htdocs的資料夾擁有者轉給nginx:

> cd /var/www/html

> mkdir htdocs

> chown -R www-data htdocs


 

建立檔案名稱: t1.php 

並儲存到  https://www.mydomain.com/htdocs/t1.php

<?php

header('Content-Type: text/html;charset=UTF-8');

$request=$_REQUEST["item1"];

echo "REQUEST=".$request."<br>";

?>


建立檔案名稱: t1.html

並儲存到  https://www.mydomain.com/htdocs/t1.html

  

<!DOCTYPE html>

<head>

  <meta charset="utf-8">

  <title>PHP Test</title>

</head>

<body>

  <form method="post" action="t1.php" name="form1">

    <input type="text" name="item1" value="">

    <input type="submit" value="確定" name="ok"> 

  </form>

</body>

</html>


開啟Chrome 

. 輸入網址 https://www.mydomain.com/htdocs/t1.html

  在欄位中輸入一些文字 abc, 

  點選確定

  

. 輸入網址 https://www.mydomain.com/htdocs/t1.php?item1=abc

  

 

開啟 Postman 

. 選擇 GET

  輸入網址 https://www.mydomain.com/htdocs/t1.php?item1=abc

  Body 選擇 nono

  點選 Send


. 選擇 GET

  輸入網址 https://www.mydomain.com/htdocs/t1.php?item1=abc

  Body 選擇 nono

  點選 Send

Ubuntu 20.04 + PHP -資料存取(二) _GET

 建立檔案名稱: t2.php 

並儲存到  https://www.mydomain.com/htdocs/t2.php

<?php

header('Content-Type: text/html;charset=UTF-8');

$get=$_GET["item1"];

echo "GET=".$get;

?>



建立檔案名稱: t2.html

並儲存到  https://www.mydomain.com/htdocs/t2.html

<!DOCTYPE html>

<head>

  <meta charset="utf-8">

  <title>PHP Test</title>

</head>

<body>

  <form method="get" action="t2.php" name="form1">

    <input type="text" name="item1" value="">

    <input type="submit" value="確定" name="ok"> 

  </form>

</body>

</html>

開啟 Chrome 

. 輸入網址 https://www.mydomain.com/htdocs/t2.html

  在欄位中輸入一些文字 abc, 

  點選確定

. 輸入網址 https://www.mydomain.com/htdocs/t2.php?item1=abc


開啟 Postman 

. 選擇 GET

  輸入網址 https://www.mydomain.com/htdocs/t2.php?item1=abc

  Body 選擇 nono

  點選 Send


. 選擇 GET

  輸入網址 https://www.mydomain.com/htdocs/t2.php?item1=abc

  Body 選擇 nono

  點選 Send