前兩天剛訂閱了bestswifter大大的小專欄,其中《2018 年將至,ios 工程師如何自我提高》這篇文章使我感觸頗深,最近剛好開始看python, 就萌生了寫一個python指令碼練練手的想法。
1. 為什麼要寫這個app?
原因之一當然是學了點東西總想練練手。
更為重要的原因則是,在寫iOS app時,每增加一個網路請求,就要寫一個json對應的model類,而構造這些model類的程式碼毫無快感可言。so,人生苦短,我用python
2. 技術棧
python最最最基礎知識
1. json反序列化
將輸入的json字串轉成對應的字典(dict) + 陣列(list)組合的形式
res = json.loads("輸入的json字串")複製程式碼
2. 字串操作
解析字典和陣列內容,生成swift對應的字串,拼接起來即可
# 遍歷字典
for (key, value) in dic.items():
# 轉換成swift格式
if isinstance(value, str):
return "String"
elif isinstance(value, float):
return "Float"
# 字串陣列拼接
result= ''.join([line+'\n' for line in res])複製程式碼
推薦兩個不錯學習資源:Python 簡單入門指北(試讀),Python教程- 廖雪峰
Cocoa APP生成
1. 介面搭建
Mac OS的介面搭建和iOS超級相似,如果會iOS程式設計,3分鐘就能搞定,這裡不做贅述。
2. 圖示生成
製作一個1024*1024的圖片,我習慣使用pixelmator,個人感覺比較簡單上手,然後生成若干張對應尺寸的圖示,這種app有很多,我用的是Prepo
3. Cocoa 執行python指令碼
NSTask已經被廢棄,應該使用Process()執行指令碼檔案
```
let buildTask = Process()
let outPip = Pipe()
let errorPipe = Pipe()
buildTask.launchPath = "/usr/bin/python"
// arguments是[String]型別,第一個元素應該為xx.py的路徑,後面元素為該py接受的引數
buildTask.arguments = args
buildTask.standardInput = Pipe()
buildTask.standardOutput = outPip
buildTask.standardError = errorPipe
// 指令碼執行完畢後的回撥
buildTask.terminationHandler = { p in
self.taskFinish()
}
buildTask.launch()
buildTask.waitUntilExit()
// 指令碼的輸出結果,即指令碼檔案的print()方法列印的內容
let data = outPip.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: String.Encoding.utf8)
// 錯誤處理, python系統錯誤
let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile()
let errorStr = String(data: errorData, encoding: String.Encoding.utf8)
if let aError = errorStr, aError != "" {
sendError("解析錯誤\r\n" + aError)
}
- arguments:指令碼引數
>let scripyPath = Bundle.main.path(forResource: "Parse", ofType: "py")! // 指令碼路徑
let para1 = "input info" // 傳入引數,通過sys.argv[I]獲取
let args = [scripyPath, para1]
buildTask.arguments = args
- standardOutput:指令碼輸出
> 執行指令碼後可通過output獲取結果
注意:指令碼的返回結果不是通過函式的return,而是通過呼叫print(infos)函式,即infos作為結果返回
let data = outPip.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: String.Encoding.utf8)
- standardError: 錯誤輸出
>解決python的exception資訊
task.terminationStatus 不等於0也能判斷為失敗
***
## 3. 封裝
Cocoa 執行python指令碼的程式碼,寫起來雖然不算特別麻煩,但總也說不是簡潔,於是重新封裝了一個類方便呼叫:[CocoaPython](https://github.com/515783034/json2swift/blob/master/json2Swift/CocoaPython.swift)
使用如下:
```swift
let script = CocoaPython(scrPath: pyPath)
script.runAsync()複製程式碼
詳細說明:
// python指令碼檔案路徑
guard let aPath = Bundle.main.path(forResource: "Parse", ofType: "py") else { return }
// args: py檔案接受的引數列表,通過sys.argv[i]訪問
// block: 完成後的回撥,包括返回值和錯誤內容
let script = CocoaPython(scrPath: aPath, args: [""]) { [weak self] in
print($0) // 返回值,所有的py中print()的內容
print($1) // py中的錯誤資訊
}
script.spliPara = "$" // 如果有多個結果,每個結果之間的分隔符,不設定則將所有的結果當成一個結果返回,即result == result[0]
script.runAsync() // 非同步執行,回撥在非同步主執行緒中呼叫
// or script.runAsync(asyncComlete: false) // 非同步執行,回撥在global中執行
// or script.runSync() // 同步執行複製程式碼
4. 資源
github地址: json2swift
OS X app: json2Swift.app
python 指令碼: json2Swift.py