Package.swift 使用在Swift 開發中替換 cocoaPod 的包管理器,簡稱 SPM,執行速度上速度更快,並且體檢最佳。
Last login: Mon Oct 12 11:25:47 on consoleshiyulong@shiyulongdeMacBook-Pro ~ % swift package --versionSwift Package Manager - Swift 5.3.0shiyulong@shiyulongdeMacBook-Pro ~ %
如何創建
(圖-0 Xcode版本號)
(圖-1 創建SPM)
細節學習錄播視頻
請關注公眾號和微信號A88888698
商務合作
商務-軟體研發:
業務範圍:APP開發、企業建站、小程序開發、軟體外包、大數據處理、大屏監控、架構諮詢、人力外派
業務經理名片:石先生
手機:13190573785 / 13031194989
使用>- 終端命令
$ mkdir Demo $ cd Demo $ swift package init --type executable Creating executable package: DemoCreating Package.swiftCreating .gitignoreCreating Sources/Creating Sources/main.swiftCreating Tests/$ swift package generate-xcodeproj generated: ./Demo.xcodeproj$ swift build Compile Swift Module 'Demo' (1 sources)Linking ./.build/debug/Demo$ ./.build/debug/Demo Hello, world!
WWDC 2018 細說 Swift 包管理工具
SwiftPM 一開始僅支持 macOS 和 Linux 平臺上的 Swift 開發,且只能通過命令行的方式來使用。在最新的 Xcode 11 中集成了 libSwiftPM,並提供了圖形化操作界面,使 Swift Package 支持 iOS/watchOS/tvOS 等平臺。
<1> 工程中添加 Package創建一個項目工程名稱為 SwiftDemo 的工程,兩種方式可以添加 Swift Package 依賴:
Xcode Menu -> File -> Swift Packages -> Add Package Dependency...
在 Xcode 12 工程中選中當前 Project 名稱 -> 選擇 Swift Packages -> 點擊 + 按鈕添加
在彈出的窗口中,可以輸入需要添加的依賴 Package 的 git 倉庫地址,複製git url,然後填寫git倉庫地址就可以,如下圖:
我們可以在 Xcode -> Preferences... -> Accounts 中添加並登錄自己的 GitHub/GitLab 帳號或公司內部私有化 Git 伺服器帳號,然後就可以在 Choose Package Respository 窗口中直接選擇你自己的或者已關注的 Swift Package.
<2> Package 概念
一個 Package (包) 由 Swift 源碼文件和一個清單文件組成。這個清單文件被命名為 Package.swift,它使用 PackageDescription 模塊來定義包的名稱。內容以及依賴關係。
Package.swift 包的清單文件,用於描述包的名稱、內容、依賴關係、支持的 Swift 版本號;
Sources: 源碼文件夾,通常包括 c/c++ 代碼和 Swift 代碼等;
Tests: 單元測試代碼
蘋果官方 Session
WWDC 2019 Session 410: Create Swift Packages
https://developer.apple.com/videos/play/wwdc2019/410/
WWDC 2018 Session 411: Getting to Know Swift Package Manager
https://developer.apple.com/videos/play/wwdc2018/411/
Swift 三方庫
「1」SwiftJSON https://github.com/SwiftyJSON/SwiftyJSON
if let statusesArray = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]], let user = statusesArray[0]["user"] as? [String: Any], let username = user["name"] as? String { }
if let JSONObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]], let username = (JSONObject[0]["user"] as? [String: Any])?["name"] as? String { }
let json = JSON(data: dataFromNetworking)if let userName = json[0]["user"]["name"].string { }
let json = JSON(data: dataFromNetworking)let result = json[999999]["wrong_key"]["wrong_name"]if let userName = result.string { } else { print(result.error)}
Usage
Initialization
import SwiftyJSONlet json = JSON(data: dataFromNetworking)Or
let json = JSON(jsonObject)Or
if let dataFromString = jsonString.data(using: .utf8, allowLossyConversion: false) { let json = JSON(data: dataFromString)}Subscript
let name = json[0].doublelet arrayNames = json["users"].arrayValue.map {$0["name"].stringValue}let name = json["name"].stringValuelet path: [JSONSubscriptType] = [1,"list",2,"name"]let name = json[path].stringlet name = json[1]["list"][2]["name"].stringlet name = json[1,"list",2,"name"].stringlet name = json[].stringlet keys:[JSONSubscriptType] = [1,"list",2,"name"]let name = json[keys].stringLoop
for (key,subJson):(String, JSON) in json { }The first element is always a String, even if the JSON is an Array
for (index,subJson):(String, JSON) in json { }Error
SwiftyJSON 4.x
SwiftyJSON 4.x introduces an enum type called SwiftyJSONError, which includes unsupportedType, indexOutOfBounds, elementTooDeep, wrongType, notExist and invalidJSON, at the same time, ErrorDomain are being replaced by SwiftyJSONError.errorDomain. Note: Those old error types are deprecated in SwiftyJSON 4.x and will be removed in the future release.
SwiftyJSON 3.x
Use a subscript to get/set a value in an Array or Dictionary
If the JSON is:
an array, the app may crash with "index out-of-bounds."a dictionary, it will be assigned to nil without a reason.not an array or a dictionary, the app may crash with an "unrecognised selector" exception.This will never happen in SwiftyJSON.
let json = JSON(["name", "age"])if let name = json[999].string { } else { print(json[999].error!) }let json = JSON(["name":"Jack", "age": 25])if let name = json["address"].string { } else { print(json["address"].error!) }let json = JSON(12345)if let age = json[0].string { } else { print(json[0]) print(json[0].error!) }
if let name = json["name"].string { } else { print(json["name"]) print(json["name"].error!) }Optional getter
if let id = json["user"]["favourites_count"].number { } else { print(json["user"]["favourites_count"].error!)}if let id = json["user"]["name"].string { } else { print(json["user"]["name"].error!)}if let id = json["user"]["is_translator"].bool { } else { print(json["user"]["is_translator"].error!)}if let id = json["user"]["id"].int { } else { print(json["user"]["id"].error!)}...Non-optional getter
Non-optional getter is named xxxValue
let id: Int = json["id"].intValuelet name: String = json["name"].stringValuelet list: Array<JSON> = json["list"].arrayValuelet user: Dictionary<String, JSON> = json["user"].dictionaryValueSetter
json["name"] = JSON("new-name")json[0] = JSON(1)json["id"].int = 1234567890json["coordinate"].double = 8766.766json["name"].string = "Jack"json.arrayObject = [1,2,3,4]json.dictionaryObject = ["name":"Jack", "age":25]Raw object
let rawObject: Any = json.objectlet rawValue: Any = json.rawValuedo { let rawData = try json.rawData() } catch { print("Error \(error)")}if let rawString = json.rawString() { } else { print("json.rawString is nil")}Existence
if json["name"].exists()Literal convertibles
For more info about literal convertibles: Swift Literal Convertibles
let json: JSON = "I'm a json"/ /IntegerLiteralConvertiblelet json: JSON = 12345// BooleanLiteralConvertiblelet json: JSON = true// FloatLiteralConvertiblelet json: JSON = 2.8765// DictionaryLiteralConvertiblelet json: JSON = ["I":"am", "a":"json"]// ArrayLiteralConvertiblelet json: JSON = ["I", "am", "a", "json"]// With subscript in arrayvar json: JSON = [1,2,3]json[0] = 100json[1] = 200json[2] = 300json[999] = 300 // Don't worry, nothing will happen// With subscript in dictionaryvar json: JSON = ["name": "Jack", "age": 25]json["name"] = "Mike"json["age"] = "25" // It's OK to set Stringjson["address"] = "L.A." // Add the "address": "L.A." in json// Array & Dictionaryvar json: JSON = ["name": "Jack", "age": 25, "list": ["a", "b", "c", ["what": "this"]]]json["list"][3]["what"] = "that"json["list",3,"what"] = "that"let path: [JSONSubscriptType] = ["list",3,"what"]json[path] = "that"// With other JSON objectslet user: JSON = ["username" : "Steve", "password": "supersecurepassword"]let auth: JSON = [ "user": user.object, // use user.object instead of just user "apikey": "supersecretapitoken"]Merging
It is possible to merge one JSON into another JSON. Merging a JSON into another JSON adds all non existing values to the original JSON which are only present in the other JSON.
If both JSONs contain a value for the same key, mostly this value gets overwritten in the original JSON, but there are two cases where it provides some special treatment:
In case of both values being a JSON.Type.array the values form the array found in the other JSON getting appended to the original JSON's array value.In case of both values being a JSON.Type.dictionary both JSON-values are getting merged the same way the encapsulating JSON is merged.In case, where two fields in a JSON have a different types, the value will get always overwritten.
There are two different fashions for merging: merge modifies the original JSON, whereas merged works non-destructively on a copy.
let original: JSON = [ "first_name": "John", "age": 20, "skills": ["Coding", "Reading"], "address": [ "street": "Front St", "zip": "12345", ]]
let update: JSON = [ "last_name": "Doe", "age": 21, "skills": ["Writing"], "address": [ "zip": "12342", "city": "New York City" ]]
let updated = original.merge(with: update)// [// "first_name": "John",// "last_name": "Doe",// "age": 21,// "skills": ["Coding", "Reading", "Writing"],// "address": [// "street": "Front St",// "zip": "12342",// "city": "New York City"// ]// ]
JSON Cafe http://www.jsoncafe.com.
網易開源Java學習資料
Spring Boot 框架介紹和使用
https://www.kdocs.cn/l/srN4cEzdm8ct?f=201
添加微信號 A88888698 或者 Neteasevava
ObjectMapper
ObjectMapper + RealmObjectMapper and Realm can be used together. Simply follow the class structure below and you will be able to use ObjectMapper to generate your Realm models:
class Model: Object, Mappable {
dynamic var name = ""
required convenience init?(map: Map) {
self.init()
}
func mapping(map: Map) {
name <- map["name"]
}
}If you want to serialize associated RealmObjects, you can use ObjectMapper+Realm. It is a simple Realm extension that serializes arbitrary JSON into Realm's List class.
To serialize Swift String, Int, Double and Bool arrays you can use ObjectMapperAdditions/Realm. It'll wrap Swift types into RealmValues that can be stored in Realm's List class.
Note: Generating a JSON string of a Realm Object using ObjectMappers' toJSON function only works within a Realm write transaction. This is because ObjectMapper uses the inout flag in its mapping functions (<-) which are used both for serializing and deserializing. Realm detects the flag and forces the toJSON function to be called within a write block even though the objects are not being modified.
三方庫合集
https://github.com/ipader/SwiftGuide/blob/master/2019/OpenSourceforSwift-Classification-MindNode.md
安裝
let package = Package( dependencies: [ .package(url: "https://github.com/kaishin/Gifu.git", from: "3.2.2") ],)
執行
override func viewDidLoad() { super.viewDidLoad() imageView.prepareForAnimation(withGIFNamed: "mugen") { print("Ready to animate!") }}
@IBAction func toggleAnimation(_ sender: AnyObject) { if imageView.isAnimatingGIF { imageView.stopAnimatingGIF() } else { imageView.startAnimatingGIF() }}