Perfect服务器开发-独立开发APP

作者: 隔壁班小明 | 来源:发表于2017-11-10 14:56 被阅读263次

    从刚刚入门IOS不久,就有一种自己开发app的冲动。但是发现一个现实又无奈的问题,没有后台啊,自己有不会弄。这篇文章是我这两个星期的努力,我觉得自己文笔太差,写不清楚的地方大家直接问我就好。
    一般APP都需要前端和后台。作为一个IOS开发,前端可以自己搞定,但是后台就没办法了。想学习一下java,PHP什么的有没有入门的地方。今天我就介绍一下我用过的两个方法来实现一下服务器的功能。
    第一个是在小波的视频里学习到的。使用MAMP和wordpress。来实现这个我推荐大家看小波视频吧。
    毕竟视频总比文字来的直接,而且大神是专业的。
    本来我用这个组合用的挺好。后来我有个要维护用户的需求怎么弄也没找到解决的办法。一顿纠结后就到了我们下面要说的perfect了。
    perfect是一款基于swift的服务器框架,也有了两年了吧。记得好早以前我就见过了,但是之前一直没成功过,这回翻出来一看。官网有了中文文档。网上也有了不少的教程了。
    既然开发那么官网一定要看的。这里先说一个坑。文档上开头说的要求swift3.0.这个事,可能是文档太久没更新了。现在是可以使用swift4的。我特意用3.0反而一直失败。坑爹。。。

    开篇先说一下我现在的环境是Xcode9.0。
    

    第一步初始化项目

    1.打开终端,新建一个PerfectDemoProject文件夹用于保存项目文件。

    mkdir PerfectDemoProject
    cd PerfectDemoProject
    

    2.初始化git----(这里没安装git的可以安装一下)

    git init
    touch README.html
    git add README.html
    git commit -m "Initial commit"
    

    3.创建Package.swift文件 -- 这个是一会编译必要的文字,这里要写上你要用的软件包

    touch Package.swift   ----创建文件
    打开文件编辑
    
    //软件包管理
    import PackageDescription
    
    let urls = [
        "https://github.com/PerfectlySoft/Perfect-HTTPServer.git",      //HTTP服务
        "https://github.com/PerfectlySoft/Perfect-MySQL.git",           //MySQL服务
        "https://github.com/PerfectlySoft/Perfect-Mustache.git"         //Mustache
    ]
    
    let package = Package(
        name: "PerfectDemoProject",
        targets: [],
        dependencies: urls.map { .Package(url: $0, versions: Version(3,0,0)..<Version(4,0,0)) }
    )
    
    这里这个Version的写法有好多种,,亲测这种最靠谱其他的多少都有点问题。。。。
    

    4.创建Sources文件夹 ---这里主要是放我们的代码。先放一个Hello World。嘿嘿

    mkdir Sources
    echo 'print("Hello World!")' >> Sources/main.swift
    

    5.编译 --- 这部分很容易出错。而且有的时候网络不好也会报错。错了请默念老天保佑然后多试几次

    swift build
    

    6.运行,成功控制台会输出Hello World --- 如果你过了上一步。那恭喜你下面没多大问题。额至少这一段

    .build/debug/PerfectDemoProject
    

    第二步放到Xcode

    第一大部分我们解决了,接下了我们把这个项目放到我们熟悉的Xcode上
    1.创建成Xcode可以运行项目

    swift package generate-xcodeproj
    

    2.在让我们打开项目看看,应该有了PerfectDemoProject.xcodeproj。用Xcode打开它

    在Build Settings中Library Search Paths检索项目软件库中增加$(PROJECT_DIR)
    

    3.编译一下
    应该没啥问题若果出错了回到1.创建成Xcode可以运行项目再来一遍

    第三步开始写服务器

    1。创建并编辑NetworkServerManager.swift

    import PerfectLib
    import PerfectHTTP
    import PerfectHTTPServer
    
    open class NetworkServerManager {
    
        fileprivate var server: HTTPServer
        internal init(root: String, port: UInt16) {
    
            server = HTTPServer.init()                          //创建HTTPServer服务器
            var routes = Routes.init(baseUri: "/api")           //创建路由器
            configure(routes: &routes)                          //注册路由
            server.addRoutes(routes)                            //路由添加进服务
            server.serverPort = port                            //端口
            server.documentRoot = root                          //根目录
            server.setResponseFilters([(Filter404(), .high)])   //404过滤
    
        }
    
        //MARK: 开启服务
        open func startServer() {
    
            do {
                print("启动HTTP服务器")
                try server.start()
            } catch PerfectError.networkError(let err, let msg) {
                print("网络出现错误:\(err) \(msg)")
            } catch {
                print("网络未知错误")
            }
    
        }
    
        //MARK: 注册路由
        fileprivate func configure(routes: inout Routes) {
    
            // 添加接口,请求方式,路径
             routes.add(method: .get, uri: "/") { (request, response) in
             response.setHeader( .contentType, value: "text/html")          //响应头
             let jsonDic = ["hello": "world"]
             let jsonString = self.baseResponseBodyJSONData(status: 200, message: "成功", data: jsonDic)
             response.setBody(string: jsonString)                           //响应体
             response.completed()                                           //响应
             }
    
        }
    
        //MARK: 通用响应格式
         func baseResponseBodyJSONData(status: Int, message: String, data: Any!) -> String {
    
            var result = Dictionary<String, Any>()
            result.updateValue(status, forKey: "status")
            result.updateValue(message, forKey: "message")
            if (data != nil) {
                result.updateValue(data, forKey: "data")
            }else{
                result.updateValue("", forKey: "data")
            }
            guard let jsonString = try? result.jsonEncodedString() else {
                return ""
            }
            return jsonString
    
        }
    
        //MARK: 404过滤
        struct Filter404: HTTPResponseFilter {
    
            func filterBody(response: HTTPResponse, callback: (HTTPResponseFilterResult) -> ()) {
                callback(.continue)
            }
    
            func filterHeaders(response: HTTPResponse, callback: (HTTPResponseFilterResult) -> ()) {
                if case .notFound = response.status {
                    response.setBody(string: "404 文件\(response.request.path)不存在。")
                    response.setHeader(.contentLength, value: "\(response.bodyBytes.count)")
                    callback(.done)
    
                } else {
                    callback(.continue)
                }
            }
        }
    }
    

    2。编辑main文件

    import PerfectLib
    import PerfectHTTP
    import PerfectHTTPServer
    
    //HTTP服务
    let networkServer = NetworkServerManager(root: "webroot", port: 8888)
    networkServer.startServer()
    

    3.运行
    成功的话,会在log看到输出

    第四步连接MySQL

    嗯电脑要安装MySQL,我是直接在官网下载安装的,也出过一些问题,这里就不说了。很多坑我也没弄明白。至于数据库编辑软件,我用的是Navicat Premium。用起来简单明了。

    1。创建并编辑DataBaseManager.swift

    import MySQL
    
    //MARK: 数据库信息
    let mysql_host = "127.0.0.1" //地址
    let mysql_user = "root"//账号
    let mysql_password = "a12345"//密码
    let mysql_database = "TestProject"//数据库名字
    
    //MARK: 表信息
    let table_account = "TestTable"  //表名字
    
    open class DataBaseManager {
    
        fileprivate var mysql: MySQL
        internal init() {
            mysql = MySQL.init()                           //创建MySQL对象
            guard connectedDataBase() else {               //开启MySQL连接
                return
            }
        }
    
        //MARK: 开启连接
        private func connectedDataBase() -> Bool {
    
            let connected = mysql.connect(host: mysql_host, user: mysql_user, password: mysql_password, db: mysql_database)
            guard connected else {
                print("MySQL连接失败" + mysql.errorMessage())
                return false
            }
            print("MySQL连接成功")
            return true
    
        }
    
        //MARK: 执行SQL语句
        /// 执行SQL语句
        ///
        /// - Parameter sql: sql语句
        /// - Returns: 返回元组(success:是否成功 result:结果)
        @discardableResult
        func mysqlStatement(_ sql: String) -> (success: Bool, mysqlResult: MySQL.Results?, errorMsg: String) {
    
            guard mysql.selectDatabase(named: mysql_database) else {            //指定database
                let msg = "未找到\(mysql_database)数据库"
                print(msg)
                return (false, nil, msg)
            }
    
            let successQuery = mysql.query(statement: sql)                      //sql语句
            guard successQuery else {
                let msg = "SQL失败: \(sql)"
                print(msg)
                return (false, nil, msg)
            }
            let msg = "SQL成功: \(sql)"
            print(msg)
            return (true, mysql.storeResults(), msg)                            //sql执行成功
    
        }
    
        /// 增
        ///
        /// - 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)
    
        }
    
        //MARK:接口使用的具体方法
        //获取account_level表中所有数据
        func mysqlGetHomeDataResult() -> [Dictionary<String, String>]? {
    
            let result = selectAllDatabaseSQL(tableName: table_level)
            var resultArray = [Dictionary<String, String>]()
            var dic = [String:String]()
            result.mysqlResult?.forEachRow(callback: { (row) in
                dic["accountLevelId"] = row[0]
                dic["name"] = row[1]
                resultArray.append(dic)
            })
            return resultArray
        }
    }
    

    嗯嗯我觉得简简单单的说完了。接下来我祝愿大家多多遇见坑(别打脸)。
    那么这些弄完的结果是什么样子呢。只要是同局域网中就能访问你的接口。至于其他网络。我还没解决,初步研究是要把当前电脑注册到公网上。我现在打算用MacOS Server试试(下了软件在升级系统呢?)。如果可以是不是就很赞了。等我消息吧!!!
    ps:虽说官方文档上有不对的地方,还是非常好,真心研究的话一定要看。加油

    相关文章

      网友评论

        本文标题:Perfect服务器开发-独立开发APP

        本文链接:https://www.haomeiwen.com/subject/sjebmxtx.html