标签 swift 下的文章

使用GCDAsyncSocket基本使用

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

import UIKit

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,GCDAsyncSocketDelegate {

    @IBOutlet weak var messageTableView: UITableView!
    @IBOutlet weak var messageTextField: UITextField!
    @IBOutlet weak var messageView: UIView!
    var socket:GCDAsyncSocket?
    override func viewDidLoad() {
        super.viewDidLoad()
        self.messageTableView.delegate = self
        self.messageTableView.dataSource = self
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardFrameChange:"), name: UIKeyboardWillChangeFrameNotification, object: nil)
        self.view.bringSubviewToFront(self.messageView)
    }
    func keyboardFrameChange(not:NSNotification)
    {
        /**
        {
        UIKeyboardAnimationCurveUserInfoKey = 7;
        UIKeyboardAnimationDurationUserInfoKey = "0.25";
        UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {375, 258}}";
        UIKeyboardCenterBeginUserInfoKey = "NSPoint: {187.5, 796}";
        UIKeyboardCenterEndUserInfoKey = "NSPoint: {187.5, 538}";
        UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 667}, {375, 258}}";
        UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 409}, {375, 258}}";
        UIKeyboardIsLocalUserInfoKey = 1;
        }
        */
        let begingFrame:CGPoint = (not.userInfo!["UIKeyboardCenterBeginUserInfoKey"]?.CGPointValue)!
        let endFrame:CGPoint = (not.userInfo!["UIKeyboardCenterEndUserInfoKey"]?.CGPointValue)!
        if (begingFrame.y - endFrame.y) > 0
        {
            // 弹出
            self.messageView.transform = CGAffineTransformMakeTranslation(0, -(begingFrame.y - endFrame.y))
        }
        else
        {
            self.messageView.transform = CGAffineTransformIdentity
        }
    }
    deinit
    {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    // 建立连接
    @IBAction func connection(sender: UIBarButtonItem) {
        //ios里实现sokcet的连接,使用C语言

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

        self.socket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_global_queue(0, 0))

        let res = try? self.socket?.connectToHost(host as String, onPort: port)
        if res != nil
        {
            print("ok")
        }
        else
        {
            print("error")
        }
    }
    // 连接完成
    func socket(sock: GCDAsyncSocket!, didConnectToHost host: String!, port: UInt16) {
        print("连接")
    }
    func socketDidDisconnect(sock: GCDAsyncSocket!, withError err: NSError!) {
        if err == nil
        {
            print("断开连接")
        }
        else
        {
            print("发生错误了。。。。")
        }
    }
    // 写入数据,需要读取下,不然后面不能进行
    func socket(sock: GCDAsyncSocket!, didWriteDataWithTag tag: Int) {
        socket?.readDataWithTimeout(-1, tag: tag)
    }
    // 读取数据
    func socket(sock: GCDAsyncSocket!, didReadData data: NSData!, withTag tag: Int) {
        let res = NSString(data: data, encoding: NSUTF8StringEncoding)
        if tag == 8888
        {
            print(res)
        }
        else if tag == 6888
        {
            NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                self.messages.append(res!)
                self.messageTableView.reloadData()
            })
        }
    }
    @IBAction func login(sender: UIBarButtonItem) {
        let str = "login:zhangsan"
        self.socket?.writeData(str.dataUsingEncoding(NSUTF8StringEncoding), withTimeout: -1, tag: 8888)
    }
    var messages:[NSString] = []
    @IBAction func sendMessage(sender: UITextField) {
        let message:NSString = sender.text!
        if(message.length > 0)
        {
            self.socket?.writeData("message:\(message)".dataUsingEncoding(NSUTF8StringEncoding), withTimeout: -1, tag: 6888)
        }
    }
    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!
    }
}

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
    }
}

CoreData基本使用

里面的代码都是在xcode已经设置好的前提下进行的,怎么在xcode中添加model之类的,就不记录了,在这里记录下代码

//
//  ViewController.swift
//  CoreData基本使用
//
//  Created by admin on 16/3/14.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit
import CoreData
class ViewController: UIViewController {
    lazy var dbFilePath:String = {
        // 数据库保存的路径,这里是设置的沙盒的缓存文件
        // let temp = "\(NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).last! as String)/testdb.sqlite"
        // 数据库的保存路径,方便查看,所以写了个固定的目录
        let temp = "/Users/admin/sqllite/testdb.sqlite"
        return temp
    }()
    lazy var fileDirectory:String = {
        // 数据库保存的路径,这里是设置的沙盒的缓存文件
        // let temp = "\(NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).last! as String)/"
        // 数据库的保存路径,方便查看,所以写了个固定的目录
        let temp = "/Users/admin/sqllite/"
        return temp
    }()
    override func viewDidLoad() {
        super.viewDidLoad()
//        self.setContext()
        self.setContextWithModelName("UserModel")
        self.insertGroup()
    }
    // 根据模型设置上下文,setContext方法会把所有的模型的表保存在同一个数据库文件中,这里可以根据那个传递的模型名称分开保存
    func setContextWithModelName(modelName:String)
    {
        let context = NSManagedObjectContext()
        let path = NSBundle.mainBundle().pathForResource(modelName, ofType: "momd")
        let model = NSManagedObjectModel(contentsOfURL: NSURL(fileURLWithPath: path!))
        let story = NSPersistentStoreCoordinator(managedObjectModel: model!)
        let savePath = "\(self.fileDirectory)\(modelName).sqlite"
        let _ = try? story.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: NSURL(fileURLWithPath: savePath), options: nil)
        context.persistentStoreCoordinator = story
        self.context = context
    }
    // 根据分组查询用户
    func selectUserWithGroup()
    {
        let request = NSFetchRequest(entityName: "Group")

        let pre = NSPredicate(format: "name = %@", argumentArray: ["管理员"])
        request.predicate = pre

        let groups:[Group]? = try? self.context?.executeFetchRequest(request) as! [Group]

        let requesUser = NSFetchRequest(entityName: "User")
        // 设置查询条件
        let preUser = NSPredicate(format: "group = %@", argumentArray: [groups![0]])
        requesUser.predicate = preUser

        let users:[User]? = try? self.context?.executeFetchRequest(requesUser) as! [User]

        for user in users!
        {
            print("用户名:\(user.name)")
            print("密码:\(user.password)")
            print("年龄:\(user.age)")
            // 这个字断是一个对象,但是需要转一下,有点麻烦啊,不知道有没有更好的方法
            let temp = user.group as! Group
            print("分组:\(temp.name)")
            print("*******************")
        }

    }
    func insertUser()
    {
        /**
        let num = 40000
        var sum = 0
        for var i = 0; i < num;i++
        {
            sum += i
        }
        print(sum)
        */
        let request = NSFetchRequest(entityName: "Group")
        // 获得所有分组
        let groups:[Group]? = try? self.context?.executeFetchRequest(request) as! [Group]

        let num = 100
        // 循环插入100个小芳
        for var i = 0; i < num;i++
        {
            let user:User = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: self.context!) as! User
            user.name = "小芳\(arc4random_uniform(100000))"
            user.age = NSNumber(unsignedInt: arc4random_uniform(100000))
            user.password = "\(arc4random_uniform(999999999))"
            user.group = groups?[Int(arc4random_uniform(UInt32((groups?.count)!)))]
            let _ = try? self.context?.save()
        }
    }
    // 插入关联表数据,这里是用户分组表
    func insertGroup()
    {
        let groupA:Group = NSEntityDescription.insertNewObjectForEntityForName("Group", inManagedObjectContext: self.context!) as! Group
        groupA.name = "管理员"
        let groupB:Group = NSEntityDescription.insertNewObjectForEntityForName("Group", inManagedObjectContext: self.context!) as! Group
        groupB.name = "游客"
        let _ = try? self.context?.save()
    }

    // 按条件查询
    func select()
    {
        let request = NSFetchRequest(entityName: "User")
        // 查询出在18岁和24岁之间的小芳
//        let pre = NSPredicate(format: "age <= %@ and age >= %@", argumentArray: [24,18])
        // 查询出名字中包含 22 的小芳
        let pre = NSPredicate(format: "name like %@", argumentArray: ["*22*"])

        request.predicate = pre

        let users:[User]? = try? self.context?.executeFetchRequest(request) as! [User]
        // 输出
        for user in users!
        {
            print("名字:\(user.name)")
            print("密码:\(user.password)")
            print("年龄:\(user.age)")
            print("***********")
        }
    }
    // 修改
    func update()
    {
        // 修改年龄
        // 1.查找到要删除的对象
        let request = NSFetchRequest(entityName: "User")

        // 条件,age 小于等于 0
        let pre = NSPredicate(format: "age <= %@", argumentArray: [0])

        request.predicate = pre;

        // 2.先读取出用户
        let users:[User]? = try? self.context?.executeFetchRequest(request) as! [User]
        // 改成 18
        for user in users!
        {
//            self.context?.deleteObject(user)
            user.age = 18
            // [self.context deleteObject:emp];
        }

        // 3.用context同步下数据库
        //所有的操作暂时都是在内存里,调用save 同步数据库
        let _ = try? self.context?.save()
    }
    // 删除
    func delete()
    {
        // 删除zhangsan
        // 1.查找到要删除的对象
        let request = NSFetchRequest(entityName: "User")

        // 条件,age字段等于 15089 的
        let pre = NSPredicate(format: "age=%@", argumentArray: [15089])

        request.predicate = pre;

        // 2.删除zhangsan
        let users:[User]? = try? self.context?.executeFetchRequest(request) as! [User]

        for user in users!
        {
            self.context?.deleteObject(user)
            // [self.context deleteObject:emp];
        }

        // 3.用context同步下数据库
        //所有的操作暂时都是在内存里,调用save 同步数据库
        let _ = try? self.context?.save()
    }
    // 添加数据
    func insert()
    {
        for var i = 0;i < 100;i++
        {
            // 创建模型对象
            let user:User = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: self.context!) as! User
            // 设置模型属性
            user.name = "小芳\(rand())"
            user.password = "\(rand())"
            user.age = NSNumber(int: rand())
            //保存 - 通过上下文操作
            if (try? self.context?.save()) == nil
            {
                print("error")
            }
            else
            {
                print("ok")
            }
        }
    }
    // 所有的操作都需要上下文
    var context:NSManagedObjectContext?
    // 获得上下文
    func setContext()
    {
        // 1.上下文 关联UserModel.xcdatamodeld 模型文件
        let context = NSManagedObjectContext()

        // 关联模型文件

        // 创建一个模型对象
        // 传一个nil 会把 bundle 下的所有模型文件(xcdatamodeld后缀的文件) 关联起来
        let model = NSManagedObjectModel.mergedModelFromBundles(nil)

        // 持久化存储调度器
        let store = NSPersistentStoreCoordinator(managedObjectModel: model!)

        // 数据库保存的路径
        let fielPath = self.dbFilePath

        //
        let res = try? store.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: NSURL(fileURLWithPath: fielPath), options: nil)

        if res != nil
        {
            context.persistentStoreCoordinator = store
        }
        // 完成上下文的初始化
        self.context = context;
    }
}

FMDB的基本使用

//
//  FMDBTestController.swift
//  微博项目
//
//  Created by zhang on 16/3/13.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class FMDBTestController: UIViewController {
    var queue:FMDatabaseQueue?
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.whiteColor()
        // 拼接文件名
        let filePath = "\(NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).last!)database.sqlite"
        print(filePath)
        self.queue = FMDatabaseQueue(path: filePath)

        // Do any additional setup after loading the view.
    }
    @IBAction func createTable(sender: AnyObject) {
        let sql = "create table if not exists t_user (id integer primary key autoincrement,name text,phone text);"
        // 创建数据库表
        // 提供了一个多线程安全的数据库实例
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let flag = database.executeUpdate(sql, withArgumentsInArray: nil)
            if (flag) {
                print("ok")
            }else{
                print("error")
            }
        })

    }

    @IBAction func insert(sender: AnyObject) {
        let sql = "insert into t_user (name,phone) values (?,?)"
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let flag = database.executeUpdate(sql, withArgumentsInArray: ["\(rand())","\(rand())"])
            if (flag) {
                print("ok")
            }else{
                print("error")
            }
        })
    }
    @IBAction func deleteTest(sender: AnyObject) {
        let sql = "DELETE FROM t_user "
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let flag = database.executeUpdate(sql, withArgumentsInArray: nil)
            if (flag) {
                print("ok")
            }else{
                print("error")
            }
        })
    }
    @IBAction func update(sender: AnyObject) {
        let sql = "UPDATE t_user SET name = '2222222'"
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let flag = database.executeUpdate(sql, withArgumentsInArray: nil)
            if (flag) {
                print("ok")
            }else{
                print("error")
            }
        })
    }
    @IBAction func selectTest(sender: AnyObject) {
        let sql = "select * from t_user;"
        self.queue?.inDatabase({ (database:FMDatabase!) -> Void in
            let res:FMResultSet? = database.executeQuery(sql, withArgumentsInArray: nil)
            var arr:NSMutableArray = NSMutableArray()
            if res != nil
            {
                while(res!.next())
                {
                    let dic:NSDictionary = ["name":"\((res?.intForColumn("name"))!)","phone":(res?.stringForColumn("phone"))!,"id":(res?.stringForColumn("id"))!]
                    arr.addObject(dic)
                }
            }

            print(arr)
        })
    }
}