分类 swift 下的文章

本地推送

发送通知

//
//  ViewController.swift
//  01-通知
//
//  Created by admin on 16/5/4.
//  Copyright © 2016年 snsnb. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }
    @IBAction func addLocalNotification(sender: UIButton) {

        /**
         // 消息发出的时间
         @NSCopying public var fireDate: NSDate?
         // 时区
         @NSCopying public var timeZone: NSTimeZone?
         // 通知周期
         public var repeatInterval: NSCalendarUnit // 0 means don't repeat
         @NSCopying public var repeatCalendar: NSCalendar?

         // location-based scheduling

         // 区域
         @available(iOS 8.0, *)
         @NSCopying public var region: CLRegion?

         // when YES, the notification will only fire one time. when NO, the notification will fire every time the region is entered or exited (depending upon the CLRegion object's configuration). default is YES.
         @available(iOS 8.0, *)
         public var regionTriggersOnce: Bool

         // 通知内容
         public var alertBody: String? // defaults to nil. pass a string or localized string key to show an alert
         // 是否显示 alertAction 设置的内容
         public var hasAction: Bool // defaults to YES. pass NO to hide launching button/slider
         // 设置提醒文字
         public var alertAction: String? // used in UIAlert button or 'slide to unlock...' slider in place of unlock
         // 设置从提醒进入app时的启动图片
         public var alertLaunchImage: String? // used as the launch image (UILaunchImageFile) when launch button is tapped
         @available(iOS 8.2, *)
         // 设置标题
         public var alertTitle: String? // defaults to nil. pass a string or localized string key

         // 声效
         public var soundName: String? // name of resource in app's bundle to play or UILocalNotificationDefaultSoundName

         // 数字
         public var applicationIconBadgeNumber: Int // 0 means no change. defaults to 0

         //
         public var userInfo: [NSObject : AnyObject]? // throws if contains non-property list types

         // category identifer of the local notification, as set on a UIUserNotificationCategory and passed to +[UIUserNotificationSettings settingsForTypes:categories:]
         @available(iOS 8.0, *)
         public var category: String?
        */
        // 创建通知
        var localNotification = UILocalNotification()

        // 设置时间
        localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)

        // 设置消息内容
        localNotification.alertBody = "哈哈哈,我是内容"
        // 设置消息标题
        if #available(iOS 8.2, *) {
            localNotification.alertTitle = "我是标题"
        } else {
            // Fallback on earlier versions
        }
        // 设置 alertAction
        localNotification.alertAction = "快点打开"
        // 设置 alertAction 是否显示,默认为显示
        localNotification.hasAction = false
        // 声效
        localNotification.soundName = UILocalNotificationDefaultSoundName
        // 图标数字
        localNotification.applicationIconBadgeNumber = 888
        // 传递自定义的信息
        localNotification.userInfo = ["body":localNotification.alertBody!,"badgeNumber":888]
        // 推送通知
        UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
    }
}

获取通知传递的值

//
//  AppDelegate.swift
//  01-通知
//
//  Created by admin on 16/5/4.
//  Copyright © 2016年 snsnb. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        /**
         public static var None: UIUserNotificationType { get } // the application may not present any UI upon a notification being received
         public static var Badge: UIUserNotificationType { get } // the application may badge its icon upon a notification being received
         public static var Sound: UIUserNotificationType { get } // the application may play a sound upon a notification being received
         public static var Alert: UIUserNotificationType { get } // the application may display an alert upon a notification being received

        */
        // ios8 之后需要授权
        if #available(iOS 8.0, *) {
            let notificationSettings = UIUserNotificationSettings(forTypes: [UIUserNotificationType.Alert,UIUserNotificationType.Sound,UIUserNotificationType.Badge], categories: nil)
            application.registerUserNotificationSettings(notificationSettings)
        }
        application.applicationIconBadgeNumber = 0
        // 只要是不是正常从图标点击进入的就会进入这个if
        if launchOptions != nil
        {
            // 注意,
            // print("通知进入")
            let view = UILabel(frame: CGRectMake(0, 120, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height - 120))
            view.backgroundColor = UIColor.darkGrayColor()
            view.numberOfLines = 0
            // 因为不能打印,所以在控件里面显示来查看效果
            // view.text = "\(launchOptions)"
            // view.text = "\(launchOptions![UIApplicationLaunchOptionsLocalNotificationKey])"
            // 可以取到传递的内容了,需要先转换下
            let notification = launchOptions![UIApplicationLaunchOptionsLocalNotificationKey] as! UILocalNotification;
            view.text = "\(notification.userInfo)"
            self.window?.rootViewController?.view.addSubview(view)
        }
        return true
    }
    // 从通知进入 app 的时候做相应的处理,在这里面进行处理的话,当程序被杀死的之后,再从通知进入应用,是无效的
    func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
        // 当应用处于活动状态时,直接 return ,后面就可以做相关的操作
        if application.applicationState == UIApplicationState.Active {
            return
        }
        // 当应用处于正在进入活动状态时,执行相应的操作
        if application.applicationState == UIApplicationState.Inactive {
            // print("跳转")
            // print(notification.userInfo)
        }
    }
}

远程推送

//
//  AppDelegate.swift
//  远程推送
//
//  Created by admin on 16/5/5.
//  Copyright © 2016年 snsnb. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        // 8.0 之后需要授权
        if #available(iOS 8.0, *) {
            // 初始化设置对象
            let setting = UIUserNotificationSettings(forTypes: [UIUserNotificationType.Badge,UIUserNotificationType.Sound,UIUserNotificationType.Alert], categories: nil)
            // 注册
            application.registerUserNotificationSettings(setting)
            // 注册远程通知
            application.registerForRemoteNotifications()
        } else {
            UIApplication.sharedApplication().registerForRemoteNotificationTypes([UIRemoteNotificationType.Badge,UIRemoteNotificationType.Sound,UIRemoteNotificationType.Alert])
        }
        // 和本地消息一样,在程序被杀死的状态下,也需要在这里获取下传递来的消息
        if launchOptions != nil {
            let lableRect = UIScreen.mainScreen().bounds
            let lable = UILabel(frame: lableRect)
            lable.numberOfLines = 0
            lable.backgroundColor = UIColor.grayColor()
            // 全部信息
            // lable.text = "\(launchOptions)"
            // 传递来的消息
            lable.text = "\(launchOptions![UIApplicationLaunchOptionsRemoteNotificationKey])"
            self.window?.rootViewController?.view.addSubview(lable)
        }
        return true
    }
    // 获得设备标识,把标识纪录下,在给apple服务器发送的时候需要用到
    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
    {
        print(deviceToken.description)
    }
    // 获得传递的消息
    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
    {
        // 可以打印消息
        print(userInfo)
    }
}

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