服务器各类型文件,Swift3一行代码将各种类型文件上传到服务器

由于之前一直在忙项目,很久没有写过一篇像样的文章了,现在手上的项目基本是完成了,正好工作时间偷个懒写两篇文章。

将相机或相册图片上传到服务器

先看看最常见的图片上传,也可以选择跳过,后面有直接的封装方法

在实际开发中,图片上传是很常见的功能,比如和朋友圈一样发布一条动态要添加几张图片,或者上传用户头像什么的,这里就介绍如何通过第三方库Alamofire进行图片上传(这里使用的是Swift,下文更新了Swift3、Alamofire4.5.0的代码版本,OC可以用AFNetworking)。

当我们上传图片通常还需要带参数,Alamofire不像AF一样具有封装好的带参数上传图片的方法,但是可以通过其他方法拼接参数,代码中会有相应注释。

如下图,我已经写好了调用相机和相册的界面,如果不会使用相机相册,请看我之前写过的一篇文章:http://www.jianshu.com/p/ab98f2fe2734

73b154c6ede4

我分别给取消按钮,拍照按钮,相册按钮设置了tag值,对应的点击方法如下(changeView是上图所示的灰色透明界面以及灰色界面上层界面):

func buttonClickedAction(sender: UIButton) {

switch sender.tag {

case 204:

//取消点击

changeView.removeFromSuperview()

case 205:

//拍照点击

changeView.removeFromSuperview()

if UIImagePickerController.isSourceTypeAvailable(.Camera) {

let picker = UIImagePickerController()

picker.sourceType = .Camera

picker.delegate = self

picker.allowsEditing = true

self.presentViewController(picker, animated: true, completion: nil)

}

else

{

self.noticeOnlyText("无法使用相机", autoClear: true, autoClearTime: 1)

}

case 206:

//相册点击

//调用相册功能,打开相册

changeView.removeFromSuperview()

let picker = UIImagePickerController()

picker.sourceType = .PhotoLibrary

picker.delegate = self

picker.allowsEditing = true

self.presentViewController(picker, animated: true, completion: nil)

default:

break

}

}

做了上述点击事件后,点击相机拍照后或者相册进行选择后就可得到照片选择器

73b154c6ede4

选择完成我们就可以用相机协议(UIImagePickerControllerDelegate,UINavigationControllerDelegate)中的imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])方法获取图片

下面的内容就直接在代码中解释:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

//获取info的类型

let type: String = (info[UIImagePickerControllerMediaType] as! String)

//如果选择的类型是图片

if type == "public.image"

{

//修正图片的位置(因为有时候上传的图片有颠倒,所以要修正一下,方法在后面)

let image = self.fixOrientation((info[UIImagePickerControllerOriginalImage] as! UIImage))

//****************保存图片到本地

//先把图片转成NSData(这里压缩图片到0.5,图片过大会造成上传时间太久或失败)

let data = UIImageJPEGRepresentation(image, 0.5)

//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 {

print(error)

}

fileManager.createFileAtPath(documentPath.stringByAppendingString("/image.png"), contents: data, attributes: nil)

//得到选择后沙盒中图片的完整路径

let filePath: String = String(format: "%@%@", documentPath, "/image.png")

// print("filePath:" + filePath)

//开始上传图片

pleaseWait()

//upLoadImageURL:上传地址

Alamofire.upload(.POST, upLoadImageURL , multipartFormData: { multipartFormData in

let lastData = NSData(contentsOfFile: filePath)

//图片二进制作为参数值,file作为参数名(参数名必须与后台一致)

multipartFormData.appendBodyPart(data: lastData!, name: "file", fileName: "image.png", mimeType: "image/png")

//拼接其他参数(可以拼接多个参数,我这里需要传一个user_id的参数)

multipartFormData.appendBodyPart(data: crrentUser!.user_id.dataUsingEncoding(NSUTF8StringEncoding)!, name: "user_id" )

}, encodingCompletion: { response in

//让选择器消失掉

picker.dismissViewControllerAnimated(true, completion: nil)

switch response {

case .Success(let upload, _, _):

upload.responseJSON(completionHandler: { (response) in

self.clearAllNotice()

if let json = response.result.value{

let code = json.objectForKey("code") as! String

// print(code)

//我这里上传成功后后台会返回code=200

if code == "200"{

self.headImageView.image = UIImage(data: data!)

let data = json.objectForKey("data") as! String

crrentUser!.head_img = data

}

}

})

case .Failure(let encodingError):

print(encodingError)

}

})

}

}

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

}

将各种类型文件上传服务器封装

Swift3后Alamofire也更新了,下面是用Alamofire4.5.0版本封装的,拷贝即可使用

import UIKit

import Alamofire

enum tbUploadType: String {

///纯文本

case textOnly = "text/plain"

///HTML文档

case html = "text/html"

///XHTML文档

case xhtml = "application/xhtml+xml"

///gif图片

case gif = "image/gif"

///jpeg图片

case jpeg = "image/jpeg"

///png图片

case png = "image/png"

///mpeg动画

case mpeg = "video/mpeg"

///任意的二进制数据

case any = "application/octet-stream"

///PDF文档

case pdf = "application/pdf"

///Word文件

case word = "application/msword"

///RFC 822形式

case rfc822 = "message/rfc822"

///HTML邮件的HTML形式和纯文本形式,相同内容使用不同形式表示

case alternative = "multipart/alternative"

///使用HTTP的POST方法提交的表单

case urlencoded = "application/x-www-form-urlencoded"

///使用HTTP的POST方法提交的表单,但主要用于表单提交时伴随文件上传的场合

case formdata = "multipart/form-data"

}

class TBUploadDataManager: NSObject {

public static let share = TBUploadDataManager()

private override init() {}

/// 上传文件

///

/// - Parameters:

/// - data: 二进制流

/// - parameters: 参数字典数组

/// - hostUrl: 服务器地址

/// - withName: 与后台协商的名字

/// - fileName: 文件名

/// - type: 上传文件类型

/// - comparBlock: 将结果返回的闭包

public func uploadLocalData(data: Data,

parameters:[String:String]?,

hostUrl:String,

withName:String,

fileName: String,

type:tbUploadType,

comparBlock:@escaping (SessionManager.MultipartFormDataEncodingResult) -> Void){

Alamofire.upload(

multipartFormData: { multipartFormData in

multipartFormData.append(data, withName: withName, fileName: fileName, mimeType: type.rawValue)

if parameters != nil{

for parameter in parameters!{

multipartFormData.append(parameter.value.data(using: .utf8)!, withName: parameter.key)

}

}

},

to: hostUrl,

encodingCompletion: { encodingResult in

//把encodingResult返回出去

comparBlock(encodingResult)

}

)

}

}

调用方法

let imagedata = UIImagePNGRepresentation(UIImage(named: "1111")!)

TBUploadDataManager.share.uploadLocalData(data: imagedata!, parameters: ["id":"12345"], hostUrl: "地址", withName: "协商名字", fileName: "1111.png", type: tbUploadType.png, comparBlock: { encodingResult in

switch encodingResult {

case .success(let upload, _, _):

upload.responseJSON { response in

debugPrint(response)

if let json = response.result.value{

print(json)

}

//

//成功要干什么

}

case .failure(let encodingError):

print(encodingError)

//失败要干什么

}

})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值