2016年2月

通过代码使用autolayout

//
//  ViewController.swift
//  autolayout-代码
//
//  Created by zhang on 16/2/29.
//  Copyright © 2016年 jin. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.constraintB()
    }
    func constraintB()
    {
        // 创建view
        let viewA = UIView()
        viewA.backgroundColor = UIColor.redColor()
        viewA.translatesAutoresizingMaskIntoConstraints = false
        let viewB = UIView()
        viewB.backgroundColor = UIColor.grayColor()
        viewB.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(viewA)
        self.view.addSubview(viewB)

        let viewAleft = NSLayoutConstraint(item: viewA, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Left, multiplier: 1.0, constant: 30)
        let viewAright = NSLayoutConstraint(item: viewA, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Right, multiplier: 1.0, constant: -30)
        let viewAtop = NSLayoutConstraint(item: viewA, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 30)
        let viewAheight = NSLayoutConstraint(item: viewA, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 60)

        let viewBright = NSLayoutConstraint(item: viewB, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: viewA, attribute: NSLayoutAttribute.Right, multiplier: 1.0, constant: 0)
        let viewBheight = NSLayoutConstraint(item: viewB, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: viewA, attribute: NSLayoutAttribute.Height, multiplier: 1.0, constant: 0)
        let viewBwidth = NSLayoutConstraint(item: viewB, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: viewA, attribute: NSLayoutAttribute.Width, multiplier: 0.5, constant: 0)
        let viewBtop = NSLayoutConstraint(item: viewB, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: viewA, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 30)
        self.view.addConstraints([viewBwidth,viewBheight,viewBright,viewBtop])
        self.view.addConstraints([viewAleft,viewAright,viewAtop,viewAheight])
    }
    func constraintA()
    {
        // 创建view
        let viewA = UIView()
        viewA.backgroundColor = UIColor.redColor()
        viewA.translatesAutoresizingMaskIntoConstraints = false
        let viewB = UIView()
        viewB.backgroundColor = UIColor.grayColor()
        viewB.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(viewA)
        self.view.addSubview(viewB)
        // 创建约束
        // 左
        let viewAleft = NSLayoutConstraint(item: viewA, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 30)
        // 下
        let viewAbottom = NSLayoutConstraint(item: viewA, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: -30)
        // 宽度
        let viewAwidth = NSLayoutConstraint(item: viewA, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: viewB, attribute: NSLayoutAttribute.Width, multiplier: 1, constant: 0)
        // 高度
        let viewAheight = NSLayoutConstraint(item: viewA, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 50)
        // 右
        let viewBright = NSLayoutConstraint(item: viewB, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: -30)
        // 下
        let viewBbottom = NSLayoutConstraint(item: viewB, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: viewA, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0)
        // 高
        let viewBheight = NSLayoutConstraint(item: viewB, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: viewA, attribute: NSLayoutAttribute.Height, multiplier: 1, constant: 0)
        // 左
        let viewBleft = NSLayoutConstraint(item: viewB, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: viewA, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 30)
        // 添加约束
        self.view.addConstraints([viewAleft,viewAbottom,viewAheight,viewAwidth])
        self.view.addConstraints([viewBbottom,viewBright,viewBheight,viewBleft])
    }
}

UIDynamicAnimator(仿真器)的使用

//
//  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()
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let touche = (touches as! NSSet).anyObject()
        self.snap((touche?.locationInView(self.view))!)
    }
    // 创建仿真器并指定仿真范围
    lazy var animator:UIDynamicAnimator = UIDynamicAnimator(referenceView: self.view)
    // 捕捉行为
    func snap(point:CGPoint)
    {
        // MARK: 创建仿真器
        self.animator.removeAllBehaviors()
        // MARK: 创建行为
        let snap = UISnapBehavior(item: self.viewA, snapToPoint: point)
        // 设置阻力
        snap.damping = 1000
        // 把行为加入到仿真器
        self.animator.addBehavior(snap)
    }
    // 重力行为仿真测试
    func gravityAttr()
    {
        // MARK: 创建仿真器

        // MARK: 创建行为
        let collision = UICollisionBehavior(items: [self.viewA])
        collision.translatesReferenceBoundsIntoBoundary = true
        let gravity = UIGravityBehavior(items: [self.viewA])
        // MARK: 属性设置
        // 重力角度,默认是 90
        gravity.angle = CGFloat(M_PI * 0.1)
        // 重力的大小,太大的话view会直接消失,应该是被重力压扁了吧。。。。
        gravity.magnitude = 1
        // 向量:具有大小和方向
        gravity.gravityDirection = CGVectorMake(3, 1)
        // MARK: 添加行为到仿真器
        self.animator.addBehavior(collision)
        self.animator.addBehavior(gravity)
    }
    // 碰撞行为仿真属性测试
    func collisionAttr()
    {
        // MARK: 创建仿真器并指定范围

        // MARK: 创建行为
        // 碰撞行为
        let collision = UICollisionBehavior(items: [self.viewA])
        // 把仿真器的bounds作为碰撞的边界
        collision.translatesReferenceBoundsIntoBoundary = true
        // 重力行为
        let gravity = UIGravityBehavior(items: [self.viewA])

        // MARK: 属性测试
        // 添加边界-线段
        let start = CGPointMake(0, self.view.bounds.size.height * 0.5 + self.viewA.bounds.size.height * 0.5)
        let end = CGPointMake(self.view.bounds.size.width, self.view.bounds.size.height * 0.5 + self.viewA.bounds.size.height * 0.5)
        collision.addBoundaryWithIdentifier("line", fromPoint: start, toPoint: end)
        // 添加一条path,view掉下来的时候会像在圆里面滚动
        let bezier = UIBezierPath(ovalInRect: CGRectMake(0, 0 - self.view.bounds.width * 0.5, self.view.bounds.width, self.view.bounds.width))
        collision.addBoundaryWithIdentifier("bezier", forPath: bezier)
        // MARK:  把仿真行为添加到仿真器中
        self.animator.addBehavior(collision)
        self.animator.addBehavior(gravity)
    }
    // 重力行为和碰撞行为,view会调到屏幕的下面停住,类似物体落地
    func gravityAndCollision()
    {
        // 创建仿真器并指定范围

        // 创建重力行为
        let gravityBehavior = UIGravityBehavior(items: [self.viewA])
        // 创建碰撞行为
        let collisionBehavior = UICollisionBehavior(items: [self.viewA])
        // 指定碰撞行为边界
        collisionBehavior.translatesReferenceBoundsIntoBoundary = true
        // 将仿真行为添加到仿真器中
        self.animator.addBehavior(gravityBehavior)
        self.animator.addBehavior(collisionBehavior)
    }
    // 重力行为,view会直接掉下来不见掉
    func gravity()
    {
        // 创建仿真器并指定仿真范围,但是直接在函数里面创建是不行的,因为这个函数执行完毕之后仿真器就被销毁了
        // 创建仿真行为
        let behavior = UIGravityBehavior(items: [self.viewA])
        // 将仿真行为添加到仿真器中
        animator.addBehavior(behavior)
    }
}

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

使用NSURLConnection下载

蛋疼的是,一个213M的文件内存峰值能到173M....
参考了这两个文章:http://blog.csdn.net/fightper/article/details/20036203
http://blog.csdn.net/lengshengren/article/details/12905697/

//
//  ViewController.swift
//  下载
//
//  Created by zhang on 16/2/28.
//  Copyright © 2016年 jin. All rights reserved.
//
/**

NSURLConnection存在的问题,iOS2.0就有了。 专门用来负责网络数据的传输,已经有10多年的历史

特点:
- 处理简单的网络操作,非常简单
- 但是处理复杂的网络操作,就非常繁琐
ASI&AFN

iOS 5.0以前,网络的下载是一个黑暗的时代
*** iOS5.0以前 通过代理的方式来处理网络数据

存在的问题:
1.下载的过程中,没有”进度的跟进“ -- 用户的体验不好
2.存在内存的峰值


解决进度跟进的问题
解决办法:通过代理的方式来处理网络数据

代理还是出现峰值, 是因为全部接受完了,再去写入
解决办法,接收到一点,写一点
//    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(click) userInfo:nil repeats:YES];
////    NSDefaultRunLoopMode : 默认的运行循环模式。 处理的优先级比NSRunLoopCommonModes低
////    NSRunLoopCommonModes : 通用的模式,在用户拖动屏幕的时候同样执行
//    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

NSURLConnection的代理,默认是在主线程运行的
需要把他的代理 移到子线程执行

下载这个任务 本身还在主线程。 所有导致进度条的更新非常卡
主线程现在在做两件事,1. 下载 2.更新进度条

NSURLConnection问题:
1. 做复杂的网络操作,需要使用代理来实现。 比如下载大文件
2. 默认下载任务在主线程工作。
3. 默认这个任务的代理也是在主线程
4. 如果添加到子线程去执行,需要主动启动运行循环
5. 只提供开始和取消。 不支持暂停。

*/



import UIKit

class ViewController: UIViewController,NSURLConnectionDataDelegate {

    @IBOutlet weak var progress: UIProgressView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        /**
         这样执行的话,是在主线程执行的
        let connection = NSURLConnection(request: request, delegate: self ,startImmediately: false)
        connection?.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
        connection?.start()
        */
        // 把网络请求放到子线程
        NSOperationQueue().addOperationWithBlock { () -> Void in
            let url = NSURL(string: "http://localhost/1.mp4")
            let request = NSMutableURLRequest(URL: url!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringCacheData, timeoutInterval: 10)
            // 这个文件比较大
            let queue = NSOperationQueue()
            queue.maxConcurrentOperationCount = 1
            let connection = NSURLConnection(request: request, delegate: self ,startImmediately: false)
            // 设置代理执行的线程在子进程
            connection?.setDelegateQueue(queue)
            // 开始
            connection?.start()

        }
    }
    var fileSize:Int64 = 0
    var currentSize:Int64 = 0
    // 接受请求
    func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse) {
        /**
            response里面的信息
            { URL: http://localhost/1.mp4 } { status code: 200, headers {
                "Accept-Ranges" = bytes;
                Connection = "Keep-Alive";
                "Content-Length" = 213811516;
                Date = "Sun, 28 Feb 2016 02:22:25 GMT";
                Etag = "\"cbe813c-528c686a2b8c0\"";
                "Keep-Alive" = "timeout=5, max=100";
                "Last-Modified" = "Thu, 07 Jan 2016 23:06:51 GMT";
                Server = "Apache/2.4.18 (Unix) OpenSSL/1.0.2f PHP/7.0.2 mod_perl/2.0.8-dev Perl/v5.16.3";
        } }
        */
        // 获得文件的总长度
        self.fileSize = response.expectedContentLength
        self.currentSize = 0
        // 避免重复写入的问题
        try? NSFileManager.defaultManager().removeItemAtPath(self.path)
    }
    // 定义保存文件的路径
    let path = "/Users/zhang/Desktop/123.mp4"
    // 接受数据
    func connection(connection: NSURLConnection, didReceiveData data: NSData) {
        // 获得文件资源文件句柄
        let handle = NSFileHandle(forWritingAtPath: path)
        // 文件不存在的时候使用nsdata进行写入
        if handle == nil
        {
            data.writeToFile(path, atomically: true)
        }
        else
        {
            // 移动指向到文件尾部,避免每次写入都吧文件替换了
            handle?.seekToEndOfFile()
            // 写入
            handle?.writeData(data)
        }
        // 一定要关闭!!!
        handle?.closeFile()
        // 当前已经下载的文件的大小,去主线程更新ui
        NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in
            self.currentSize += data.length
            self.progress.progress = Float(Float64(self.currentSize) / Float64(self.fileSize))
        }
    }
    func connectionDidFinishLoading(connection: NSURLConnection) {
        print("连接完成")
    }
    func connection(connection: NSURLConnection, didFailWithError error: NSError) {
        print("错误啦")
    }

}