开发一个不那么另类的 Swift 服务端框架:Pjango

发布于: 2017-06-18 17:11
阅读: 2159
评论: 0
喜欢: 15

这是一款 Swift 服务端开发框架,在「GitHub」开源。

项目使用 Apache 2.0 许可,任何违反许可的行为都将承担责任。

引言

用 Python 开发过服务端的同学可能会对Pjango这个名字眼熟。没错,名字来源于著名的 Python 服务端框架Django。为什么要叫 Pjango 呢,因为它是基于 Perfect 开发的,Perfect 全家桶在工程里有着举足轻重的作用。最终取了这个名字,向二者致敬。

本框架基于 Perfect,并做了 MVC 设计,读者可以使用 MVC 来构建你的网站。

写这篇博文的目的是想找一两个熟悉 Django 又熟悉 Swift for Linux 的小伙伴一起开发,一起讨论。

Demo

Demo 的地址已和核心框架一起上传 GitHub,这里就简单介绍一下。

配置和路由

这两项分别在 Demo 的Settings.swiftUrls.swift中。

Settings.swift:

import Foundation
import Pjango_Core

public func pjangoUserSetSettings() {
    
    // Pjango
    
    #if os(macOS)
        WORKSPACE_PATH = "/Users/Enum/Developer/macOS/Pjango/Workspace"
    #else
        WORKSPACE_PATH = "/media/psf/Home/Developer/macOS/Pjango/Workspace"
    #endif
    
    DEBUG_LOG = true

    
    
    // Django
    
    BASE_DIR = ""

    TEMPLATES_DIR = "templates"

    STATIC_URL = "static"
    
    DATABASE = PCDataBaseConfig.init(param: [
        "ENGINE": PCDataBaseEnginType.mysql,
        "NAME": "Pjango_default",
        "USER": "github",
        "PASSWORD": "enumsgithub.",
        "HOST": "127.0.0.1",
        "PORT": UInt16(3306),
    ])!
}

Urls.swift:

import Foundation
import Pjango_Core

public func pjangoUserSetUrls() -> [PCUrlConfig] {
    
    return [
        
        pjangoUrl("", IndexView.self, "index"),
        pjangoUrl("time_zone", TimeZoneView.self, "time_zone"),
        
    ]
    
}

用过 Django 的同学一定会觉得这个画面十分眼熟。实现细节都在Pjango-Core中,如果读者只想使用框架,就不必去了解背后实现的细节。

Django 的路由是用正则匹配的,很不幸的是 Pjango 的路由最终会向着 Perfect-HTTPServer 中的规则走,并不会使用正则。但功能都是可以实现的。

数据库无关页面

写 View 和 Web

某些动态的页面可能不需要经过数据库,页面上或许只有个时间,或者只有个动态字符串。使用 Pjango 开发,只需要在 Web 中遵守 Mustache 模板规则嵌入变量,在服务端代码中返回一个字典去一一对应就可以了。

class IndexView: PCView {
    
    override var templateName: String {
        return "index.html"
    }
    
    override var viewParam: PCViewParam? {
        return [
            "_pjango_url_timezone": pjangoUrlReverse("time_zone"),
            "_pjango_param_time": Date.init().stringValue,
            "_pjango_param_msg": "Msg from Pjango"
        ]
    }
    
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"> 
    <title>Welcome to Pjango</title>
    <link rel="stylesheet" target="_blank" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css">  
    <script src="http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<h1 class="text-center">Welcome to Pjango!</h1>
<h4 class="text-center"></h4>
<h4 class="text-center"></h4>

<div class="text-center">
    <button type="button" class="btn btn-default" onclick="window.open('')">See More Time Zone</button>
</div>

</body>
</html>

查看效果:http://enumsblog.com:8080

数据库相关页面

数据库相关的页面,常见的就是列出表的相关内容了。使用 Pjango,只需要编写 Model,Pjango 在运行时会自动检查表是否存在,如果表不存在会自动创建跟模型对应的表。

1、写 Model

class TimeZoneModel: PCModel {
    
    override var tableName: String {
        return "TimeZone"
    }
    
    var zone = PCDataBaseField.init(name: "ZONE", type: .string, length: 3)
    var memo = PCDataBaseField.init(name: "MEMO", type: .string, length: 50)
    
    override func registerFields() -> [PCDataBaseField] {
        return [
            zone, memo
        ]
    }
}

2、写 View 和 Web

class TimeZoneView: PCListView {
    
    override var templateName: String {
        return "time_zone.html"
    }
    
    override var querySet: Array<PCModel>? {
       return TimeZoneModel.queryObjects()
    }
    

}

如果需要展示额外字段,重载这个方法即可:


override func viewParamUserField(withModel model: PCModel) -> PCViewParam? {
    let model = model as! TimeZoneModel
    let formatter = DateFormatter.init()
    formatter.timeZone = TimeZone.init(identifier: model.zone.value as! String)
    formatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
    return [
        "_pjango_param_table_TimeZone_TIME": formatter.string(from: Date.init())
    ]
}
    

页面也需要遵守 Mustache 模板规则,嵌入包含表格的代码:

<body>
<table class="table">
   <thead>
      <tr>
         <th>ZONE</th>
         <th>MEMO</th>
         <th>TIME</th>
      </tr>
   </thead>
   <tbody>

   </tbody>
</table>

</body>

查看效果:http://enumsblog.com:8080/time_zone

效果中由于 Swift 在 Linux 下时区设置存在 bug,因此时间显示是错误的。在 macOS 中没有这个问题,感兴趣的同学可以下载源码,在 macOS 上查看效果。

结语

说了这么多,只是想让 Swift 服务端之路走得更顺利点罢了,欢迎感兴趣的同学加入。

发邮件给我:blog@enumsblog.com


Thanks for reading.

All the best wishes for you! 💕