美文网首页swift开发iOS学习Swift
Swift-一步步教你上传头像 & swift利用Ala

Swift-一步步教你上传头像 & swift利用Ala

作者: 高扬先生 | 来源:发表于2016-10-11 09:14 被阅读4312次

    Swift-一步步教你上传头像

    先前有人私信我说上传有问题,博主确认了下,发现是路径的问题,把Object-C的代码转变成Swift后路径就出了问题,不知道原因,推测可能是Swift本身的问题,所以博主换了一种路径方式,大家注意,关于路径和文件操作的,后面博主要写一篇博客来进行说明,有兴趣的可以看看,或者自己查查资料。

    上一篇中列出了Alamofire中GET和POST的使用方法,这里来介绍如何用Alamofire以表单形式来上传头像。
    前面写过一篇Object-C的上传头像,这里代码是一样的,只是语言不一样,想看的请点击这里:http://blog.csdn.net/codingfire/article/details/51781194
    下面来看看用Swift怎么来上传头像:

    20160718165454746.gif

    1.可拍照,可选择相册中图片:
    AlertController前面单独说过,我们不陌生,需要看的就是UIImagePickerController了,

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            let actionSheet = UIAlertController(title: "上传头像", message: nil, preferredStyle: .ActionSheet)
            let cancelBtn = UIAlertAction(title: "取消", style: .Cancel, handler: nil)
    
    
            let takePhotos = UIAlertAction(title: "拍照", style: .Destructive, handler: {
                (action: UIAlertAction) -> Void in
    //判断是否能进行拍照,可以的话打开相机
                if UIImagePickerController.isSourceTypeAvailable(.Camera) {
                    let picker = UIImagePickerController()
                    picker.sourceType = .Camera
                    picker.delegate = self
                    picker.allowsEditing = true
                    self.presentViewController(picker, animated: true, completion: nil)
    
                }
                else
                {
                    print("模拟其中无法打开照相机,请在真机中使用");
                }
    
            })
            let selectPhotos = UIAlertAction(title: "相册选取", style: .Default, handler: {
                (action:UIAlertAction)
                -> Void in
                //调用相册功能,打开相册
                let picker = UIImagePickerController()
                picker.sourceType = .PhotoLibrary
                picker.delegate = self
                picker.allowsEditing = true
                self.presentViewController(picker, animated: true, completion: nil)
    
            })
            actionSheet.addAction(cancelBtn)
            actionSheet.addAction(takePhotos)
            actionSheet.addAction(selectPhotos)
            self.presentViewController(actionSheet, animated: true, completion: nil)
    
    
        }
    

    2.选择一张照片后进入代理方法

     func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
            let type: String = (info[UIImagePickerControllerMediaType] as! String)
    
            //当选择的类型是图片
            if type == "public.image"
            {
    
                //修正图片的位置
                let image = self.fixOrientation((info[UIImagePickerControllerOriginalImage] as! UIImage))
                //先把图片转成NSData
                let data = UIImageJPEGRepresentation(image, 0.5)
    
     //这里为先前的写法,在Swift中路径有变化
     //--------------------------------------------------//           
                **//图片保存的路径
                //这里将图片放在沙盒的documents文件夹中
                let DocumentsPath:String = NSHomeDirectory().stringByAppendingString("Documents")
    
                //文件管理器
                let fileManager = NSFileManager.defaultManager()
    
                //把刚刚图片转换的data对象拷贝至沙盒中 并保存为image.png
                try! fileManager.createDirectoryAtPath(DocumentsPath, withIntermediateDirectories: true, attributes: nil)
                fileManager.createFileAtPath(DocumentsPath + "/image.png", contents: data, attributes: nil)
    
                //得到选择后沙盒中图片的完整路径
                let filePath = DocumentsPath + "/image.png"**
    
    //--------------------------------------------------//
    
    
    
    
                //图片保存的路径
                //这里将图片放在沙盒的documents文件夹中
    
                //Home目录
                let homeDirectory = NSHomeDirectory()
                let documentPath = homeDirectory + "/Documents"
                //文件管理器
                let fileManager: NSFileManager = NSFileManager.defaultManager()
                //把刚刚图片转换的data对象拷贝至沙盒中 并保存为image.png
                do {
                    try fileManager.createDirectoryAtPath(documentPath, withIntermediateDirectories: true, attributes: nil)
                }
                catch let error {
                }
                fileManager.createFileAtPath(documentPath.stringByAppendingString("/image.png"), contents: data, attributes: nil)
                //得到选择后沙盒中图片的完整路径
                let filePath: String = String(format: "%@%@", documentPath, "/image.png")
                print("filePath:" + filePath)
                Alamofire.upload(.POST, "http://192.168.3.16:9060/client/updateHeadUrl", multipartFormData: { multipartFormData in
                    let lastData = NSData(contentsOfFile: filePath)
    
                    multipartFormData.appendBodyPart(data: lastData!, name: "image")
    
                    }, encodingCompletion: { response in
                        picker.dismissViewControllerAnimated(true, completion: nil)
                        switch response {
                        case .Success(let upload, _, _):
                            upload.responseJSON(completionHandler: { (response) in
                                print(response)
                                self.imageView.image = UIImage(data: data!)
    
                            })
    
                        case .Failure(let encodingError):
                            print(encodingError)
                        }
    
                })
    
    
            }
        }
    

    3.你会发现有时候上传的图片是旋转了90度的,下面来修正照片位置:

    func fixOrientation(aImage: UIImage) -> UIImage {
            // No-op if the orientation is already correct
            if aImage.imageOrientation == .Up {
                return aImage
            }
            // We need to calculate the proper transformation to make the image upright.
            // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
            var transform: CGAffineTransform = CGAffineTransformIdentity
            switch aImage.imageOrientation {
            case .Down, .DownMirrored:
                transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height)
                transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
            case .Left, .LeftMirrored:
                transform = CGAffineTransformTranslate(transform, aImage.size.width, 0)
                transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
            case .Right, .RightMirrored:
                transform = CGAffineTransformTranslate(transform, 0, aImage.size.height)
                transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
            default:
                break
            }
    
            switch aImage.imageOrientation {
            case .UpMirrored, .DownMirrored:
                transform = CGAffineTransformTranslate(transform, aImage.size.width, 0)
                transform = CGAffineTransformScale(transform, -1, 1)
            case .LeftMirrored, .RightMirrored:
                transform = CGAffineTransformTranslate(transform, aImage.size.height, 0)
                transform = CGAffineTransformScale(transform, -1, 1)
            default:
                break
            }
    
            // Now we draw the underlying CGImage into a new context, applying the transform
            // calculated above.
    
    
            //这里需要注意下CGImageGetBitmapInfo,它的类型是Int32的,CGImageGetBitmapInfo(aImage.CGImage).rawValue,这样写才不会报错
            let ctx: CGContextRef = CGBitmapContextCreate(nil, Int(aImage.size.width), Int(aImage.size.height), CGImageGetBitsPerComponent(aImage.CGImage), 0, CGImageGetColorSpace(aImage.CGImage), CGImageGetBitmapInfo(aImage.CGImage).rawValue)!
            CGContextConcatCTM(ctx, transform)
            switch aImage.imageOrientation {
            case .Left, .LeftMirrored, .Right, .RightMirrored:
                // Grr...
                CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.height, aImage.size.width), aImage.CGImage)
            default:
                CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.width, aImage.size.height), aImage.CGImage)
            }
    
            // And now we just create a new UIImage from the drawing context
            let cgimg: CGImageRef = CGBitmapContextCreateImage(ctx)!
            let img: UIImage = UIImage(CGImage: cgimg)
            return img
        }
    

    以上方法亲测无误,需要的小伙伴放入正确的地址来进行测试。
    Demo下载地址:https://github.com/codeliu6572/Swift_upload_headerImage

    原文链接:http://blog.csdn.net/codingfire/article/details/51943286

    补充:

    swift利用Alamofire上传图片

    后台的接口数据如下:
    接口名称 上传头像
    接口地址 /data/upload
    传入参数 MultipartFile file, String phoneId, Integer phoneType
    传出结果 //0 ok, 1 空文件, 2 文件写失败

    分析: 接口需要传三个参数,file为图片的二进制文件,String类型的phoneId,Integer类型的phoneType

    Alamofire上传图片,用于传递参数的类是multipartFormData,利用multipartFormData.appendBodyPart添加参数即可,内部会自动出来参数

    private func upload(uploadImage: UIImage,address: String,scale: Double) {
    
            Alamofire.upload(.POST, address, multipartFormData: { (multipartFormData) in
                
                    let data = UIImageJPEGRepresentation(uploadImage, scale)
                    let imageName = String(NSDate()) + ".png"
    
                //multipartFormData.appendBodyPart(data: ,name: ,fileName: ,mimeType: )这里把图片转为二进制,作为第一个参数
                multipartFormData.appendBodyPart(data: data!, name: "file", fileName: imageName, mimeType: "image/png")
                
                //把剩下的两个参数作为字典,利用 multipartFormData.appendBodyPart(data: name: )添加参数,
                //因为这个方法的第一个参数接收的是NSData类型,所以要利用 NSUTF8StringEncoding 把字符串转为NSData 
                let param = ["phoneId" : HCUserModel.sharedInstance.phoneId!, "phoneType" : "1"]
    
               //遍历字典
               for (key, value) in param {
               multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
                }
                
            }) { (encodingResult) in
                switch encodingResult {
                case .Success(let upload, _, _):
                    upload.responseJSON(completionHandler: { (response) in
                        if let myJson = response.result.value {
                            
                            if myJson as! NSObject == 0 {
                             print("上传成功")                            
                            }else {
                                print("上传失败")
                            }
                        }
                    })
                case .Failure(let error):
                    print(error)
                }
            }
        }
    

    原文链接:http://blog.csdn.net/aa31140105/article/details/51893318

    相关文章

      网友评论

      • 939aa01ddf09:感觉博主的分享。
        我有几个疑问:
        1、博主设置了图片可编辑,但是读取出来的图片为什么还是原图片?
        2、获取设置沙盒文件路径,以及保存操作是否过于复杂?
        3、Swift4.0里面的图片旋转方法不支持(Swift4.0可以参考:https://www.cnblogs.com/lilefan/p/6698424.html)。
      • 冰三尺:最新的Alamofire没有这个方法了吧?为什么我找不到
        939aa01ddf09:博主的Alamofire应该是旧版本
      • 布袋的世界:觉得很有用
        高扬先生: @布袋的世界 多图上传在此基础上用一个for循环即可
        布袋的世界:@高扬先生 不知道有没有多图上传的
        高扬先生: @布袋的世界 谢谢

      本文标题:Swift-一步步教你上传头像 & swift利用Ala

      本文链接:https://www.haomeiwen.com/subject/wvnvyttx.html