2017-04-22 23:21:15 bianruifeng 阅读数 752

首先,上官网 https://www.perfect.org 官方文档可是有中文的哦。
然后,GitHub Demo https://github.com/PerfectlySoft/PerfectTemplate

开始操作:
下载Demo :

git clone https://github.com/PerfectlySoft/PerfectTemplate.git
cd PerfectTemplate
swift build  //编译
.build/debug/PerfectTemplate  //立刻启动服务器,可以选择不执行
swift package generate-xcodeproj  //获得一个xcode的macos的项目,生成:PerfectTemplate.xcodeproj 启动文件

通过Xcode 打开项目,就可以直接运行了,比较有意思的是如果你打一个断点(断点并没有什么效果),在拖拽取消断点的时候,Xcode 就会停止编译。

在执行 swift build 时候报错如下:
这里写图片描述

应该是网络原因造成的,我在尝试数次后成功了,终端显示如下:

这里写图片描述
中间编译内容比较多,仅截取了开始跟结尾
这里写图片描述

如果你在Xcode中运行着代码再去执行 启动服务器的命令:.build/debug/PerfectTemplate 终端会报出如下问题,停止Xcode运行,重新运行.build/debug/PerfectTemplate命令。
这里写图片描述

一个非常好的教程,共三部分:http://www.cnblogs.com/ludashi/p/6145344.html
以及部署:http://www.jianshu.com/p/ae96107ec1ae

2016-05-05 17:29:40 taoerit 阅读数 2955

1 功能需求:

      1 在Swift下使用GCDAsyncSocket实现简单的信息收发功能

   2 Mac下为tcp服务器,windows下为tcp客户端 

2 效果图:



3 swift代码:需要导入GCDAsyncSocket库文件,可去github下载

import UIKit


class ViewController:UIViewController,GCDAsyncSocketDelegate {


   @IBOutletvar startBtn:UIButton!

    

   @IBOutletvar msgTextView:UITextView!

    

   var serverSocket:GCDAsyncSocket!

    

   let serverPort:UInt16 =9050

    

   var clientSockets:NSMutableArray!

    

   var startIsSuccessful =false

    

    var mainQueue =dispatch_get_main_queue()

    

   @IBOutletvar inputTextInput:UITextField!

    

   @IBOutletvar sendBtn:UIButton!

    

   overridefunc viewDidLoad() {

       super.viewDidLoad()

        

        clientSockets =NSMutableArray()

       msgTextView.backgroundColor =UIColor.grayColor()

        msgTextView.text ="接收的客户端消息:\n"

        

    }

    

    

    // 发送消息按钮

   @IBActionfunc sendBtnClick(sender:AnyObject) {

        

       ifclientSockets.count ==0 {

           return

        }

        

       let msg =inputTextInput.text!

  

        // 1.处理请求,返回数据给客户端 ok

        let serviceStr:NSMutableString =NSMutableString()

        serviceStr.appendString(msg)

        serviceStr.appendString("\n")

        

       let wSocket =clientSockets[0]//此处只使用一个客户端连接

        wSocket.writeData(serviceStr.dataUsingEncoding(NSUTF8StringEncoding), withTimeout: -1, tag: 0)

        

    }

    

    //开启服务按钮

   @IBActionfunc startServer(sender:AnyObject) {

        

        // 1 初始化 我是mac

        serverSocket =GCDAsyncSocket()

        

        // 2 设置委托

        serverSocket.delegate =self

        serverSocket.delegateQueue =dispatch_get_global_queue(0,00)

        

        

       do {

            tryserverSocket.acceptOnPort(serverPort)

            startIsSuccessful =true

           self.startBtn.enabled =false

            print("server start successful!")

        }

       catch {

           startBtn.backgroundColor =UIColor.redColor()

            print("server start error!")

        }

    }

    

   /*

    * 有客户端的socket连接到服务器

    */

   func socket(srvSocket:GCDAsyncSocket!, didAcceptNewSocket cSocket:GCDAsyncSocket!) {

       

        // 1 保存socket 判断socket是否存在,不存在就添加

        

       if cSocket ==nil {

            print("client sock nil")

           return

        }

        

       ifclientSockets.containsObject(cSocket) {

           print("已经存在!")

           return

        }

       else {

             //不存在,添加

            clientSockets.addObject(cSocket)

        }

        

        // 2 返回消息

        let serviceStr:NSMutableString =NSMutableString()

        serviceStr.appendString("login successful\n")

        cSocket.writeData(serviceStr.dataUsingEncoding(NSUTF8StringEncoding), withTimeout: -1, tag: 0)

        

        // 3.监听客户端有没有数据上传

        //timeout -1 代表不超时

        //tag 标识作用,现在不用,就写0

        cSocket.readDataWithTimeout(-1, tag:0)

        

    }

    

   /*

    * 读取客户端请求的数据

    */

   func socket(cSocket:GCDAsyncSocket!, didReadData data:NSData!, withTag tag:Int) {

        

        // 1 获取客户的发来的数据 ,把 NSData NSString

       let readClientDataString:NSString? =NSString(data: data, encoding:NSUTF8StringEncoding)

       print(readClientDataString!)

        

        // 2 主界面ui 显示数据

        dispatch_async(mainQueue, {

            

             let showStr:NSMutableString =NSMutableString()

            showStr.appendString(self.msgTextView.text)

             showStr.appendString(readClientDataString!asString)

             showStr.appendString("\n")

           self.msgTextView.text = showStrasString

            

            })

        

        // 3.处理请求,返回数据给客户端 ok

        let serviceStr:NSMutableString =NSMutableString()

        serviceStr.appendString("ok\n")

        cSocket.writeData(serviceStr.dataUsingEncoding(NSUTF8StringEncoding), withTimeout: -1, tag: 0)

        

        // 4每次读完数据后,都要调用一次监听数据的方法

        cSocket.readDataWithTimeout(-1, tag:0)

        

    }

    

    

}




xcode 7.1.1

项目源码地址:http://download.csdn.net/detail/taoerit/9582653



GCDAsyncSocket 下载地址:包含tcp和udp,共4个文件 http://download.csdn.net/detail/taoerit/9809540


2016-02-08 21:02:54 u014388424 阅读数 9172

编者语:今天是大年初一,先和大家简单说一句猴年快乐!

       

       你认识Swift或者是在客户端,因为它是苹果用来开发客户端的新一代语言。在Swift开源后苹果让它不仅在MacOS/iOS上跑,也运行到了Linux ,而第三方公司RemObject把Swift带到了Android,也带到了Windows(Windows Form/WPF/Universal Windows App) 。可以说Swift已经是一个完整的跨平台语言了。但有人会说Swift缺少了做服务器端的能力,如网站,接口等,现在Perfect就是一个很不错的项目能完成网站开发/数据接口等服务端的工作。今天开始我会介绍给大家。

       Perfect让Swift在服务器端跑起来了,它是开源的。你可以通过官网http://www.perfect.org (这个需要佛跳墙)了解它,也可以从它的Github上下载最新的源码 https://github.com/PerfectlySoft/Perfect/。以下是在Perfect网站上一个重要的介绍, 这真的是一个很cool 的项目。

       

         Perfect主要提供了三块主要的功能一个是从服务器端到客户端都适用的PerfectLib(包括了一些简单的操作如JSON或者是WebHandler的相关操作),其次是一个FastCGI和HTTP服务的容器去支持Perfect在服务端的运行,还有一个Connector这个主要用来和一些服务器基础服务打交道(如和Apache接入,还有数据库链接等现阶段支持MySQL,MongoDB, PostgerSQL还有SQLite).

        Perfect在服务器端是如何运作的?我们先来看看。

         

       从上面的图可以看出,这和我们的rails思想差不多,如果你熟悉.NET MVC/Java Spark !/Ruby on Rails是,那再迁移过来是很快的事情。我们来看看如何来创建一个Perfect项目并创建一个简单的WebAPI。

      1.  先把Perfect从Github拉下来 git clone https://github.com/PerfectlySoft/Perfect.git

      2.  下载完后,第一件事情不是编码,是把Perfect模版添加到Xcode内。模版放在Extras目录下(如图)

      

       然后只需要把Extras/Xcode Templates/Perfect 拷贝到/Users/用户名/Library/Developer/Xcode/Templates/Project Templates/ 下即可。添加完后你打开Xcode就可以看到Perfect模版了。

       

       3. 把上面开发环境配置好现在就可以开始创建Perfect项目了,我们先来创建一个WorkSpace(如果你不太懂看下图),叫PerfectSample

       

       4. 创建成功后,分别先把PerfectLib,PerfectServer,MySQL引入WorkSpace中,由于用到不同的基础服务所以必须引入。PerfectLib你可以理解成Perfect框架,而PerfectServer是启动支持Perfect的类似IIS/Apache的容器,MySQL是需要介入MySQL Connector

      

      5. 利用Perfect模版创建PerfectWeb项目,如图我创建了一个HelloWorld的项目。如图这个和我们创建Cocoa Framework一致的。当然你可以不需要这个模版,直接从Cocoa Framework模版上创建。

      

      项目里面就包含了一个Handler和一个对应的mustache模版。但这个时候还是不能运行的,你必须把PerfectLib/MySQL Connector引用进来,如下图,这里需要注意PerfectLib是引用PerfectLibOSX版本。

      

     完成添加这两个库后还需要配置Buiding Scheme ,如图,因为你启动需要PerfectServer所以你需要把executable改成PerfectServer.app ,并把Shared项目钩上。

     

     6. 对PerfectHandler.swift进行修改


import PerfectLib
import MySQL


let HOST = "你的数据库链接"
let USER = "你的帐号"
let PASSWORD = "你的密码"
let SCHEME = "你的数据库"

public func PerfectServerModuleInit() {
    
    Routing.Handler.registerGlobally()
    Routing.Routes["GET", ["/"]] = { (_:WebResponse) in return PerfectHandler() }
    print("\(Routing.Routes.description)")
}

//Create a handler for index Route
class PerfectHandler: RequestHandler {
    
    func handleRequest(request: WebRequest, response: WebResponse) {
        
        response.addHeader("Content-Type", value: "application/json")
        response.addHeader("Content-Type", value: "text/html; charset=utf-8")
        
        let mysql = MySQL()
        let connect = mysql.connect(HOST, user: USER, password: PASSWORD)
        if(connect)
        {
            let sres = mysql.selectDatabase(SCHEME)
            if(sres)
            {
                
                let sres2 = mysql.query("SELECT name,memo FROM Info")
                
                if(sres2)
                {
                    let results = mysql.storeResults()!
                    
                    
                    
                    if(results.numRows()==0)
                    {
                        do{
                            
                            
                            let encoder = JSONEncoder()
                            let data = try encoder.encode(["result": ""])
                            response.appendBodyString(data)
                        }
                        catch{
                            response.setStatus(500, message: "Could not create data")
                        }
                    }
                    else
                    {
                        var dataArray:Array<AnyObject> = []
                        var dict = Dictionary<String,String>()
                        while let row = results.next() {
                            
                            dict["name"]=row[0];
                            dataArray.append(dict)
                            
                        }
                        
                        print(NSJSONSerialization.isValidJSONObject(dataArray))
                        
                        
                        do {
                            
                            
                            let dataFinal = try NSJSONSerialization.dataWithJSONObject(dataArray, options:NSJSONWritingOptions(rawValue:0))
                            
                            let string = NSString(data: dataFinal, encoding: NSUTF8StringEncoding)
                            
                            let tee : String = string as! String
                            response.appendBodyString(tee)
                        }
                        catch{
                            response.setStatus(500, message: "Could not create data")
                        }
                        
                        
                        
                    }
                    
                    
                    
                    
                    results.close()
                }
            }
            mysql.close()
        }
        response.requestCompletedCallback()
    }
}
        7. 运行,当运行时会启动 PerfectServer.app,然后在浏览器输入0.0.0.0:8080就可以看到JSON结果了。

        

        结果:

        


       好!一个简单的Web API就完成了,当然这是平平无奇,但是用Swift完成了服务器端的开发是感觉不错的事情。Perfect是一个开始,完成度也有待提高,但是我相信很快会有质的飞跃,如即将支持的ORM等。文档不足也是一个很致命的原因,我相信也会很快改善。

       介绍一个不错的blog(需要佛跳墙) http://code-me-dirty.blogspot.co.uk/2016/02/creating-perfect-swift-server.html ,当然你可以看我的连载。

       今天先说到这里,接下来我会让Perfect在Linux上飞,下篇见

2016-05-05 17:38:09 taoerit 阅读数 6961

1 功能需求:

      1 在Swift下使用GCDAsyncSocket实现简单的信息收发功能

     2 Mac下为tcp客户端,windows下为tcp服务器 

2 效果图:

 

【swift代码支持swift2.0 和swift3.3,文尾有下载地址】

3 swift代码:需要导入GCDAsyncSocket库文件,可去github下载

import UIKit



class ViewController:UIViewController,GCDAsyncSocketDelegate {

   @IBOutletvar serveripInput:UITextField!

   @IBOutletvar msgInput:UITextField!

   @IBOutletvar conBtn:UIButton!

   @IBOutletvar sendBtn:UIButton!

   @IBOutletvar msgView:UITextView!

   let serverPort:UInt16 =9050

   var clientSocket:GCDAsyncSocket!

   var mainQueue =dispatch_get_main_queue()

   overridefunc viewDidLoad() {

       super.viewDidLoad()

    }



    //连接服务器按钮事件

   @IBActionfunc conBtnClick(sender:AnyObject) {

       do {

           clientSocket =GCDAsyncSocket()

            clientSocket.delegate =self

            clientSocket.delegateQueue =dispatch_get_global_queue(0,0)

            try clientSocket.connectToHost(serveripInput.text!, onPort: serverPort)

           conBtn.backgroundColor =UIColor.blueColor()

        }
       catch {

           print("error")

           conBtn.backgroundColor =UIColor.redColor()

        }


    }

    

   func socket(sock:GCDAsyncSocket!, didConnectToHost host:String!, port:UInt16) {

        print("与服务器连接成功!")

       clientSocket.readDataWithTimeout(-1, tag:0)

    }

    
   func socketDidDisconnect(sock:GCDAsyncSocket!, withError err:NSError!) {

       print("与服务器断开连接")

    }



   func socket(sock:GCDAsyncSocket!, didReadData data:NSData!, withTag tag:Int) {

        // 1 获取客户的发来的数据 ,把 NSData 转 NSString,如果包含非UTF8字符时,data不为空,但是转NSString时为空,去掉非UTF8字符串即可

       let readClientDataString:NSString? =NSString(data: data, encoding:NSUTF8StringEncoding)

       print(readClientDataString!)

        // 2 主界面ui 显示数据

        dispatch_async(mainQueue, {

            

            let showStr:NSMutableString =NSMutableString()

            showStr.appendString(self.msgView.text)

            showStr.appendString(readClientDataString!asString)

            showStr.appendString("\n")

           self.msgView.text = showStrasString

            

        })

        

        // 3.处理请求,返回数据给客户端 ok

        let serviceStr:NSMutableString =NSMutableString()

        serviceStr.appendString("ok\n")

       clientSocket.writeData(serviceStr.dataUsingEncoding(NSUTF8StringEncoding), withTimeout: -1, tag: 0)

        

        // 4每次读完数据后,都要调用一次监听数据的方法

       clientSocket.readDataWithTimeout(-1, tag:0)

    }

    

    //发送消息按钮事件

   @IBActionfunc sendBtnClick(sender:AnyObject) {

        // 1.处理请求,返回数据给客户端 ok

        let serviceStr:NSMutableString =NSMutableString()

         serviceStr.appendString(self.msgInput.text!)

        serviceStr.appendString("\n")

       clientSocket.writeData(serviceStr.dataUsingEncoding(NSUTF8StringEncoding), withTimeout: -1, tag: 0)

    }

}

 

 

 

注意:

1 xcode版本: 7.1.1  swift 2.0

withTimeout为-1时,不自动断开,如果是其他值,比如为2,2秒回自动断开

 

swift2.0 项目下载地址:http://download.csdn.net/detail/taoerit/9582648

swift3.3 项目下载地址:https://download.csdn.net/download/taoerit/10574442

GCDAsyncSocket 下载地址:包含tcp和udp,共4个文件 http://download.csdn.net/detail/taoerit/9809540

 

 

 

 

2015-10-24 09:53:00 weixin_33696822 阅读数 2

swift的函数跟脚本语言有很多神似之处。 如果有一天用swift开发服务器 ,很期待哇(一切皆有可能,毕竟人家说要跑在Linux上),?

从参数个数来看

  1. 无参数

     func myFunc()->Int{
    
     }

     

  2. 单参数

     func myFunc(first:Int)->Int{
    
     }

     

  3. 多参数

    func myFunc(first:Int, other:Int)->Int{
    
     }     

     

从返回值来看

  1. 无返回值

     func myFunc(){
     }

     

  2. 单个返回值

     func myFunc()->Bool{
     }

     

  3. 多值返回

     func myFunc()->(min:Int, max:Int)

     

    元组的成员不需要在函数中返回时命名,因为它们的名字已经在函数返回类型中有了定义

    var ret = myFunc()
     print("min:\(ret.min), max:\(ret.max)")

     

从参数名称来看

函数参数都有一个外部参数名(external parameter name)和一个本地参数名(local parameter name)。

第一个参数省略其外部参数名,第二个以后的参数使用其本地参数名作为自己的外部参数名。所有参数需要有不同的本地参数名,但可以共享相同的外部参数名

func myFunc(first:Int, first A:Int, first B:Int){
}
// 但是这么写外部参数名真的好么?
myFunc(12, first: 1, first: 3);

 

使用外部函数名可以使得函数可以用一句话表达清楚,并且使得函数体内部可读,能表达出函数的明确意图。

 

忽略外部参数名

如果如下:

func myFunc( first:Int,  A:Int)->Int{

     return 10
}
myFunc(12, A: 1) // 这样A,B 也是外部参数名 

 

那么如何实现 直接调用myFunc(12,1)这样的函数调用呢?

func myFunc(first:Int, _ A:Int)->Int{

     return 10
}
myFunc(12,1) // OK

 

默认参数

func myFunc(parameter: Int = 12)->Int{
    return  parameter
}

myFunc()  // 

 

将带有默认值的参数放在函数参数列表的最后。这样可以保证在函数调用时,非默认参数的顺序是一致的,同时使得相同的函数在不同情况下调用时显得更为清晰。

 

可变参数

可变参数可以接受0个或者多个值

func myFunc(par:Double ...)->Double{

    var total:Double = 0

    for number in par {
        total += number
    }
    return total
}

myFunc(1,2,3,4,5)
myFunc(1,5,8.9)

 

一个函数最多只能有一个可变参数 如果函数有一个或多个带默认值的参数,而且还有一个可变参数,那么把可变参数放在参数表的最后

func myFunc(a:Double = 10, par:Double ...   )->Double{

    var total:Double = a

    for number in par {
     total += number
    }
    return total
}

myFunc(par: 1,2,3,4) // 20
myFunc(14, par: 1,2,3,4) // 24

 

变量参数

就是在函数体内可以改变这个参数的值,默认我们都知道 参数值是个let

var str = "Hello, playground"
func myFunc(var str:String)-> String{
    str = "@"+str
    return str
}
myFunc(str)

 

对变量参数所进行的修改在函数调用结束后便消失了,并且对于函数体外是不可见的。变量参数仅仅存在于函数调用的生命周期中。

 

输入输出参数

上面的可变参数仅仅是对函数体内可变,但如何使得一个函数可以修改参数的值,并且想要在这些修改在函数调用结束后仍然存在。那么就有了 In-Out 参数,这个有点像C++的引用。

你只能将变量作为输入输出参数。你不能传入常量或者字面量(literal value),因为这些量是不能被修改的。当传入的参数作为输入输出参数时,需要在参数前加&符,表示这个值可以被函数修改。

输入输出参数不能有默认值,而且可变参数不能用 inout 标记。如果你用 inout 标记一个参数,这个参数不能被 var 或者 let 标记。

func swap(inout a:Int, inout _ b:Int){
    let tmp = a
    a = b
    b = tmp
}
var a = 3      // not let a = 3
var b = 107
//swap(3, 107) error
swap(&a, &b)


函数类型(Function Types)
()->Void

(Int, Int)->(Int, Int)

//...

函数类型的使用跟普通类型的使用方法相同,可作为参数类型,也可以是返回类型

 

函数可以嵌套

func myFunc(a: Int, b:Int)->(Int)->Int{

    func addAB(a:Int, _ b:Int)->Int{
        return a + b;
    }

    func retFunc(a:Int)->Int{
        return addAB(a , b) * b
    }

    return retFunc
}

(myFunc(3, b: 4))(3)

对于函数,也许还有些其他的东西,比如自定义操作符,重载,还有泛型,还有一块函数式编程(我之前的文章也有相关介绍,对于这块我还是相当感兴趣的)。这类的知识我会慢慢补上的,哈哈,大家一起学习,有问题的地方请帮我指出。

转载于:https://www.cnblogs.com/Ohero/p/4906258.html

没有更多推荐了,返回首页