序言:
1.以下代碼中的意義舶沛,會在代碼里解釋,用比較容易理解的詞語注釋窗价,若有晦澀之處如庭,可私信于我。
2.現(xiàn)已假設(shè)讀者閱讀過我的另外兩篇文章??
Swift Perfect開發(fā)你的服務(wù)器(初級版)
Swift Perfect開發(fā)你的服務(wù)器(中級版)
3.準備Peffect助手工具:Perfect Assistant 3.0創(chuàng)建服務(wù)器項目
基于“以上”編譯成功后撼港,在默認的main.swift文件里坪它,全部清空,然后替換成我的代碼:
// 導(dǎo)入所需要的庫
import PerfectLib
import PerfectHTTP
import PerfectHTTPServer
import PerfectMustache
import Foundation
let root = "./webroot"
// 配置服務(wù)器端口帝牡、根目錄等
let server = HTTPServer()
server.serverPort = 8181
server.documentRoot = root
// 配置路由往毡,BasicRoutes在RoutesManager.swift的代碼里,往下看,go go go
let basic = BasicRoutes()
server.addRoutes(Routes(basic.routes))
/* 另一種方法
* var routes = Routes()
* routes.add(method: .post, uri: "/testUpload", handler: TestUpload)
* server.addRoutes(routes)
*/
do {
try server.start() // 開啟服務(wù)器
} catch PerfectError.networkError(let err, let msg) {
print("Netword error thrown: \(err) \(msg)")
}
打開項目否灾,新建RoutesManager.swift卖擅,添加以下代碼
import Foundation
import PerfectLib
import PerfectHTTP
import PerfectHTTPServer
// 路由
class BasicRoutes {
var routes: [Route] {
return [
/*
1.這里定義接口,為客戶端服務(wù)墨技,我們請求的方法惩阶,和url,在這里設(shè)置扣汪。
2.由于我們還沒有新建TestUpload方法断楷,所以這里暫時會報錯,先不管崭别,往下看,go go go
*/
Route(method: .post, uri: "/api/testUploadImage", handler: TestUpload)
]
}
}
新建路由助手類RoutesHelper.swift冬筒,然后添加下面代碼
import Foundation
import PerfectLib
import PerfectHTTP
let testStr = "CRTest"
/*
圖片上傳方法:
1. request是客戶端的請求,有些參數(shù)我們可在這里獲取
2.response是我們給客戶端的響應(yīng)茅主,想要返回的數(shù)據(jù)舞痰,在這設(shè)置
*/
func TestUpload(request: HTTPRequest, response: HTTPResponse) {
do{
guard let uploads = request.postFileUploads, uploads.count >= 1 else {
let successArray: [String:Any] = ["result":"false", "msg":"請選擇正確的圖片數(shù)量"]
let jsonStr = try successArray.jsonEncodedString()
try response.setBody(json: jsonStr)
response.completed()
return
}
/*
這里的iOSTime參數(shù)是我在客戶端那邊傳過來的當(dāng)前本地時間。
其實是可以在這設(shè)置的诀姚,但由于客戶端和服務(wù)器的精確時間并不一致响牛,
所以采用了客戶端的時間為標(biāo)準,同時也鍛煉了我們傳參的能力
*/
guard let currentTime = request.param(name: "iOSTime") else {
return
}
#if os(Linux)
// Dir.workingDir.parentDir拿到父目錄赫段,也可在本地運行打印看看是什么東東
guard let parentPath = Dir.workingDir.parentDir?.path else {
return
}
// 設(shè)置我們存放圖片的路徑呀打,同時nginx的配置也要與這個路徑有關(guān)聯(lián),看過我之前的文章會不陌生糯笙!
let fileDir = Dir(parentPath + "usr/local/sources/pictures/" + currentTime)
do {
try fileDir.create()
} catch {
Log.error(message: "\(error)")
}
#else
let fileDir = Dir(Dir.workingDir.path + "webroot/pictures")
do {
try fileDir.create()
} catch {
Log.error(message: "\(error)")
}
#endif
// 官網(wǎng)上摘取的代碼
if let uploads = request.postFileUploads, uploads.count > 0 {
var ary = [[String:Any]]()
var pathArr = [String]()
for upload in uploads {
ary.append([
"fieldName": upload.fieldName,
"contentType": upload.contentType,
"fileName": upload.fileName,
"fileSize": upload.fileSize,
"tmpFileName": upload.tmpFileName
])
// move file to webroot
let thisFile = File(upload.tmpFileName)
if (thisFile.path != "") {
do {
// 本地存放路徑(本地即為Mac環(huán)境運行)
let resultPath = fileDir.path + upload.fileName
// Ubuntu存放到數(shù)據(jù)庫的路徑
let realPath = "http://www.crios.cn/pictures/" + "\(currentTime)" + upload.fileName
let _ = try thisFile.moveTo(path: resultPath, overWrite: true)
// 這里會報錯贬丛,DataBaseManager.swift還沒有創(chuàng)建,先不管给涕,會在下一步執(zhí)行
let sql = DataBaseManager().createTable(tableName: testStr + currentTime)
if sql.success {
#if os(Linux)
let _ = DataBaseManager().insertDatabaseSQL(tableName: testStr + currentTime, key: "path,currentTime", value: "'\(realPath)','\(currentTime)'")
#else
let _ = DataBaseManager().insertDatabaseSQL(tableName: testStr + currentTime, key: "path,currentTime", value: "'\(resultPath)','\(currentTime)'")
#endif
}
#if os(Linux)
pathArr.append(realPath)
#else
pathArr.append(resultPath)
#endif
} catch {
let successArray: [String:Any] = ["success": 1, "result": "\(error)", "msg": "失敗"]
Log.error(message: "\(error)")
let jsonStr = try successArray.jsonEncodedString()
try response.setBody(json: jsonStr)
response.completed()
}
}
}
do {
// 通用的返回數(shù)據(jù)豺憔,可參照我的代碼或官網(wǎng)的额获、設(shè)定
let successArray: [String:Any] = ["success": 1, "result": pathArr, "msg": "成功"]
let jsonStr = try successArray.jsonEncodedString()
try response.setBody(json: jsonStr)
response.completed()
} catch {
let successArray: [String:Any] = ["success": 1, "result": "后臺格式錯誤", "msg": "成功"]
let jsonStr = try successArray.jsonEncodedString()
try response.setBody(json: jsonStr)
response.completed()
}
}
}catch{
Log.error(message: "\(error)")
}
}
新建MySQL數(shù)據(jù)庫管理類
import Foundation
import PerfectMySQL
// MARK: 數(shù)據(jù)庫信息
#if os(Linux) // 在Ubuntu下
let user = "root"
let password = "你的密碼"
let dataBase = "test1" // test1數(shù)據(jù)庫是自己在Navicat Premium圖形工具里創(chuàng)建的
let host = "0.0.0.0"
#else
let user = "root"
let password = "你的密碼"
let dataBase = "CRTest"
let host = "0.0.0.0"
#endif
open class DataBaseManager {
fileprivate var mysql: MySQL
internal init() {
mysql = MySQL.init() //創(chuàng)建MySQL對象
guard connectedDataBase() else { //開啟MySQL連接
return
}
}
// MARK: 開啟連接
private func connectedDataBase() -> Bool {
let connected = mysql.connect(host: host, user: user, password: password, db: dataBase)
guard connected else {
print(mysql.errorMessage())
return false
}
print("MySQL Connect Success")
return true
}
// MARK: 執(zhí)行SQL語句
/// 執(zhí)行SQL語句
///
/// - Parameter sql: sql語句
/// - Returns: 返回元組(success:是否成功 result:結(jié)果)
@discardableResult
func mysqlStatement(_ sql: String) -> (success: Bool, mysqlResult: MySQL.Results?, errorMsg: String) {
guard mysql.selectDatabase(named: dataBase) else { //指定database
let msg = "NO\(dataBase)Database"
print(msg)
return (false, nil, msg)
}
let successQuery = mysql.query(statement: sql) //sql語句
guard successQuery else {
let msg = "SQL_Error: \(sql)"
print(msg)
return (false, nil, msg)
}
let msg = "SQL_Success: \(sql)"
print(msg)
return (true, mysql.storeResults(), msg) //sql執(zhí)行成功
}
/// 創(chuàng)建表 (查詢是否有此表,若否焕阿,則創(chuàng)建)
func createTable(tableName: String) -> (success: Bool, mysqlResult: MySQL.Results?, errorMsg: String){
let insert = "SELECT * FROM \(tableName)"
let statement = mysqlStatement(insert)
if !statement.success {
let SQL = "CREATE TABLE \(tableName) (id INT(10) PRIMARY KEY AUTO_INCREMENT, path VARCHAR(255), companyName VARCHAR(255),phoneNumber VARCHAR(255))"
return mysqlStatement(SQL)
}
return mysqlStatement(insert)
}
// CREATE TABLE samples (id INT PRIMARY KEY AUTO_INCREMENT, created_at DATETIME, location POINT, reading JSON)
/// 增
///
/// - Parameters:
/// - tableName: 表
/// - key: 鍵 (鍵咪啡,鍵,鍵)
/// - value: 值 ('值', '值', '值')
func insertDatabaseSQL(tableName: String, key: String, value: String) -> (success: Bool, mysqlResult: MySQL.Results?, errorMsg: String){
let SQL = "INSERT INTO \(tableName) (\(key)) VALUES (\(value))"
return mysqlStatement(SQL)
}
/// 刪
///
/// - Parameters:
/// - tableName: 表
/// - key: 鍵
/// - value: 值
func deleteDatabaseSQL(tableName: String, key: String, value: String) -> (success: Bool, mysqlResult: MySQL.Results?, errorMsg: String) {
let SQL = "DELETE FROM \(tableName) WHERE \(key) = '\(value)'"
return mysqlStatement(SQL)
}
/// 改
///
/// - Parameters:
/// - tableName: 表
/// - keyValue: 鍵值對( 鍵='值', 鍵='值', 鍵='值' )
/// - whereKey: 查找key
/// - whereValue: 查找value
func updateDatabaseSQL(tableName: String, keyValue: String, whereKey: String, whereValue: String) -> (success: Bool, mysqlResult: MySQL.Results?, errorMsg: String) {
let SQL = "UPDATE \(tableName) SET \(keyValue) WHERE \(whereKey) = '\(whereValue)'"
return mysqlStatement(SQL)
}
/// 查所有
///
/// - Parameters:
/// - tableName: 表
/// - key: 鍵
func selectAllDatabaseSQL(tableName: String) -> (success: Bool, mysqlResult: MySQL.Results?, errorMsg: String) {
let SQL = "SELECT * FROM \(tableName)"
return mysqlStatement(SQL)
}
/// 查
///
/// - Parameters:
/// - tableName: 表
/// - keyValue: 鍵值對
func selectAllDataBaseSQLwhere(tableName: String, keyValue: String) -> (success: Bool, mysqlResult: MySQL.Results?, errorMsg: String) {
let SQL = "SELECT * FROM \(tableName) WHERE \(keyValue)"
return mysqlStatement(SQL)
}
// 獲取數(shù)據(jù)庫某個表中的所有數(shù)據(jù)
func mysqlGetUserDataResult(tableName: String) -> [Dictionary<String, String>]? {
let result = selectAllDatabaseSQL(tableName: tableName)
var resultArray = [Dictionary<String, String>]()
var dic = [String:String]()
result.mysqlResult?.forEachRow(callback: { (row) in
dic["uuid"] = row[1]
resultArray.append(dic)
})
return resultArray
}
}