分类 网络 下的文章

socket服务端(GCDAsyncSocket)

main.swift

//
//  main.swift
//  socket服务器
//
//  Created by admin on 16/3/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import Foundation
let server = Server()
server.start(52013)
NSRunLoop.currentRunLoop().run()

Server.swift

//
//  Server.swift
//  socket服务器
//
//  Created by admin on 16/3/16.
//  Copyright © 2016年 jin. All rights reserved.
//


class Server: NSObject,GCDAsyncSocketDelegate {
    var serverSocket:GCDAsyncSocket?
    var clientSockets:[GCDAsyncSocket] = []
    override init()
    {
        super.init()
        self.serverSocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
    }
    // 开启服务器
    func start(port:UInt16)
    {
        let res = try? self.serverSocket?.acceptOnPort(port)
        if res != nil
        {
            print("ok")
        }
        else
        {
            print("error")
        }
    }
    // 当有新的客户端时会调用这个方法,注意要把客户端socket保存起来,不然客户端连上立马就退出了
    func socket(sock: GCDAsyncSocket!, didAcceptNewSocket newSocket: GCDAsyncSocket!) {
        // 保存起来
        self.clientSockets.append(newSocket)
        // 客户端先读取下数据,不然无法服务器无法接受客户端的数据
        newSocket.readDataWithTimeout(-1, buffer: nil, bufferOffset: 0, tag: self.clientSockets.count)
    }
    // 接受客户端的数据,当客户端又数据的时候会调用这个方法
    func socket(sock: GCDAsyncSocket!, didReadData data: NSData!, withTag tag: Int) {
        // 转换二进制数据
        var str = NSString(data: data, encoding: NSUTF8StringEncoding)
        // 去掉换行和回车
        str = str?.stringByReplacingOccurrencesOfString("\n", withString: "")
        str = str?.stringByReplacingOccurrencesOfString("\r", withString: "")
        // 把字符串按照 : 符号分隔成数组
        let strArr = str?.componentsSeparatedByString(":")
        // 初始化返回值字符串
        var outputStr:NSString = "不能识别"
        // 对不同类型的消息进行处理
        if strArr?.count > 1
        {
            switch(strArr![0])
            {
            case "message":
                outputStr = "\(strArr![0])说\(strArr![1])"
                break
            case "login":
                outputStr = "\(strArr![1])登录成功"
                break
            default:
                break
            }
        }
        if strArr![0] == "quit"
        {
            // 关闭连接
            sock.disconnect()
            // 从socket数组中移除
            self.clientSockets.removeAtIndex(self.clientSockets.indexOf(sock)!)
        }
        outputStr = "\(outputStr)\n"
        // 往客户端写入数据
        sock.writeData(outputStr.dataUsingEncoding(NSUTF8StringEncoding), withTimeout: -1, tag: tag)
    }
    // 在服务器写数据的时候会调用,这里必须实现并且read下数据,不然上面的方法就只能执行一次
    func socket(sock: GCDAsyncSocket!, didWriteDataWithTag tag: Int) {
        sock.readDataWithTimeout(-1, tag: tag)
    }
}

iOS中socket的基本使用

//
//  ViewController.swift
//  socket练习-聊天室客户端
//
//  Created by admin on 16/3/16.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController,NSStreamDelegate,UITableViewDelegate,UITableViewDataSource {

    @IBOutlet weak var messageTableView: UITableView!
    @IBOutlet weak var messageTextField: UITextField!
    var inputStream:NSInputStream?
    var outputStream:NSOutputStream!
    override func viewDidLoad() {
        super.viewDidLoad()
        self.messageTableView.delegate = self
        self.messageTableView.dataSource = self
    }
    // 建立连接
    @IBAction func connection(sender: UIBarButtonItem) {
        //ios里实现sokcet的连接,使用C语言

        // 1.与服务器通过三次握手建立连接
        let host:CFString = "127.0.0.1"
        let port:UInt32 = 52013

        // 2.定义输入输出流

        var readStream:Unmanaged<CFReadStream>?
        var writeStream:Unmanaged<CFWriteStream>?

        // 3.分配输入输出流的内存空间
//        CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);

        CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, &readStream, &writeStream)

        // 4.把C语言的输入输出流转成OC对象

        self.inputStream = readStream?.takeRetainedValue()
        self.outputStream = writeStream!.takeUnretainedValue()

//        _inputStream = (__bridge NSInputStream *)readStream;
//        _outputSteam = (__bridge NSOutputStream *)(writeStream);
//        

        // 5.设置代理,监听数据接收的状态
        self.inputStream?.delegate = self
        self.outputStream?.delegate = self
        // 把输入输入流添加到主运行循环(RunLoop)
        // 主运行循环是监听网络状态
        self.inputStream?.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
        self.outputStream?.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)

        // 6.打开输入输出流
        self.inputStream?.open()
        self.outputStream.open()
    }
    @IBAction func login(sender: UIBarButtonItem) {
        let str = "login:zhangsan"
        self.sendData(str)
        let res = self.readData()
        print(res)
    }
    var messages:[NSString] = []
    @IBAction func sendMessage(sender: UITextField) {
        let message:NSString = sender.text!
        if(message.length > 0)
        {
            self.sendData("message:\(message)")
            let res = self.readData()
            self.messages.append(res)
            self.messageTableView.reloadData()
        }
    }
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return self.messages.count
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("MessageCell")
        cell?.textLabel?.text = self.messages[indexPath.row] as String
        return cell!
    }
    // 代理方法,在不同的状态会调用这个方法
    func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
        switch(eventCode)
        {
        case NSStreamEvent.OpenCompleted:
                print("建立连接成功,形成输入输出流通道")
            break
        case NSStreamEvent.HasBytesAvailable:
            print("可以读取数据")
            break
        case NSStreamEvent.HasSpaceAvailable:
            print("可以发送数据")
            break
        case NSStreamEvent.ErrorOccurred:
            print("发生错误")
            break
        case NSStreamEvent.EndEncountered:
            print("正常断开连接")
            // 关闭输入输出流,并从主运行循环中移除
            self.inputStream?.close()
            self.inputStream?.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
            self.outputStream.close()
            self.outputStream?.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
            break
        default:
            break
        }
    }
    // 发送数据
    func sendData(dataString:NSString)
    {
        let data:NSData = dataString.dataUsingEncoding(NSUTF8StringEncoding)!
        self.outputStream.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
    }
    func readData()->NSString
    {

        var buffer = [UInt8](count: 1024, repeatedValue: 0)
        let len = self.inputStream?.read(&buffer, maxLength: buffer.count)
        var res:NSString = ""
        //
        if len > 0
        {
            res = NSString(bytes: buffer, length: buffer.count, encoding: NSUTF8StringEncoding)!
        }
        return res
    }
}

VFL的使用

和http://jinblog.com/archives/520.html的文章两个例子完成的效果一样,注意格式

//
//  ViewController.swift
//  UIDynamic的使用
//
//  Created by admin on 16/2/29.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var viewA: UIView!
    override func viewDidLoad() {
        super.viewDidLoad()
        self.constraintB()
    }
    func constraintB()
    {
        // 创建控件
        let viewA = UIView()
        viewA.translatesAutoresizingMaskIntoConstraints = false
        viewA.backgroundColor = UIColor.blueColor()
        self.view.addSubview(viewA)
        let viewB = UIView()
        viewB.translatesAutoresizingMaskIntoConstraints = false
        viewB.backgroundColor = UIColor.brownColor()
        self.view.addSubview(viewB)
        // 创建约束
        // 水平
        let viewAh = NSLayoutConstraint.constraintsWithVisualFormat("H:|-30-[viewA]-30-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["viewA" : viewA])
        // 垂直
        let viewAv = NSLayoutConstraint.constraintsWithVisualFormat("V:|-30-[viewA(50)]-[viewB(==viewA)]", options: NSLayoutFormatOptions.AlignAllRight, metrics: nil, views: ["viewA" : viewA,"viewB" : viewB])
        // 比例值,需要用构造方法来完成
        let viewBwidth = NSLayoutConstraint(item: viewB, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: viewA, attribute: NSLayoutAttribute.Width, multiplier: 0.5, constant: 0)
        // 添加约束
        self.view.addConstraint(viewBwidth)
        self.view.addConstraints(viewAh)
        self.view.addConstraints(viewAv)
//        let viewB
    }
    func constaintA()
    {
        // 创建控件
        let viewA = UIView()
        viewA.translatesAutoresizingMaskIntoConstraints = false
        viewA.backgroundColor = UIColor.blueColor()
        self.view.addSubview(viewA)
        let viewB = UIView()
        viewB.translatesAutoresizingMaskIntoConstraints = false
        viewB.backgroundColor = UIColor.brownColor()
        self.view.addSubview(viewB)

        // 创建约束
        // 水平方向,左右有间距,要加“|”,并把间距用“-”分隔
        let viewAh = NSLayoutConstraint.constraintsWithVisualFormat("H:|-30-[viewA]-[viewB(==viewA)]-30-|", options: NSLayoutFormatOptions.AlignAllBottom, metrics: nil, views: ["viewA" : viewA,"viewB" : viewB])
        // 垂直方向,左边没有约束就不要加 “|”,直接固定数字,直接写数字,不要加等号
        let viewAv = NSLayoutConstraint.constraintsWithVisualFormat("V:[viewA(50)]-30-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["viewA" : viewA])
        self.view.addConstraints(viewAh)
        self.view.addConstraints(viewAv)
        // 没有对齐,传这个值就行
        let viewBv = NSLayoutConstraint.constraintsWithVisualFormat("V:[viewB(==viewA)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["viewA" : viewA,"viewB" : viewB])
        self.view.addConstraints(viewBv)
    }
}

AFNetworking基本使用

//
//  ViewController.swift
//  AFNet使用
//
//  Created by admin on 16/2/29.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.upload()
    }
    func upload()
    {
        let configuretion = NSURLSessionConfiguration.defaultSessionConfiguration()
        let manager = AFHTTPSessionManager(sessionConfiguration: configuretion)
        // 获得文件url
        let pathUrl = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("1.jpg", ofType: nil)!)
        manager.POST("http://test.com/upload.php", parameters: nil, constructingBodyWithBlock: { (formData:AFMultipartFormData) -> Void in
            // 添加文件
            try? formData.appendPartWithFileURL(pathUrl, name: "uploadFile[]", fileName: "newImage.jpg", mimeType: "image/jpeg")
            // try? formData.appendPartWithFileURL(pathUrl, name: "uploadFile[]", fileName: "newImage.jpg", mimeType: "image/jpeg")
            }, progress: { (progress:NSProgress) -> Void in
                print(progress)// 上传进度
            }, success: { (task:NSURLSessionDataTask, data:AnyObject?) -> Void in
                print(data) // 返回的数据
            }) { (task:NSURLSessionDataTask?, error:NSError) -> Void in
                print(error) // 错误
        }
    }
    func get()
    {
        let manager = AFHTTPSessionManager()
        let data = ["username":"张三","password":"zhang"]
        manager.GET("http://test.com/login.php", parameters: data, success: { (task:NSURLSessionDataTask, data:AnyObject?) -> Void in
            print(data)
            }) { (task:NSURLSessionDataTask?, error:NSError) -> Void in
                print(error.userInfo)
        }
    }
    func post()
    {
        let manage = AFHTTPSessionManager()
        let data = ["username":"张三","password":"zhang"]
        manage.POST("http://test.com/login.php", parameters: data, progress: { (progress:NSProgress) -> Void in
            print(progress)
            }, success: { (task:NSURLSessionDataTask, data:AnyObject?) -> Void in
                print(data)
            }) { (task:NSURLSessionDataTask?, error:NSError) -> Void in
                print(error)
        }
    }
}

NSURLSession的使用

//
//  ViewController.swift
//  session使用
//
//  Created by zhang on 16/2/28.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController,NSURLSessionDownloadDelegate {

    @IBOutlet weak var progress: UIProgressView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.downloadA()
    }
    // oc的代理是强引用,swift的不是
    lazy var session:NSURLSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: self, delegateQueue: nil)
    // 存放task
    var task:NSURLSessionDownloadTask?
    // 存放断点续传的数据
    var resumeData:NSData?
    // 可以显示下载进度,暂停继续的下载
    @IBAction func start(button:UIButton)
    {
        // 初始化task
        self.task = session.downloadTaskWithURL(NSURL(string: "http://localhost/1.mp4")!)
        // 初始化data
        self.resumeData = nil
        // 开始
        self.task?.resume()
    }
    // 停
    @IBAction func stop(button:UIButton)
    {
        // 停止
        self.task?.cancelByProducingResumeData({ (data:NSData?) -> Void in
            // 记录当前data
            self.resumeData = data
            // 置空task
            self.task = nil
        })
        print(self.task)
    }
    // 继续
    @IBAction func resume(button:UIButton)
    {
        if self.resumeData != nil
        {
            // 根据上次暂停时的data初始化task
            self.task = session.downloadTaskWithResumeData(self.resumeData!)
            // 初始化data
            self.resumeData = nil
            // 继续
            self.task?.resume()
        }
        else
        {
            print("没有暂停过的任务或者有任务正在运行")
        }

    }
    // 下载完成时执行
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
        print("下载完成了")
    }
    // 下载进度发生变化时执行
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in
            self.progress.progress = Float(Float64(totalBytesWritten) / Float64(totalBytesExpectedToWrite))
        }
    }
    // 下载和解压zip,需要用到第三方的库
    func downloadA()
    {
        let downloadTask = NSURLSession.sharedSession().downloadTaskWithURL(NSURL(string: "http://localhost/zip.zip")!) { (url:NSURL?, response:NSURLResponse?, error:NSError?) -> Void in
            SSZipArchive.unzipFileAtPath(url?.path, toDestination: "/Users/zhang/Desktop/path/")
        }
        downloadTask.resume()
    }
    // 发送请求
    func request()
    {
        let session = NSURLSession.sharedSession()
        let dataTask = session.dataTaskWithURL(NSURL(string: "http://localhost/demo.json")!) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in

            print(try? NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments))
        }
        dataTask.resume()
    }
}