swift文件服务器,Swift3一行代码将各种类型文件上传到服务器
由于之前一直在忙项目,很久没有写过一篇像样的文章了,现在手上的项目基本是完成了,正好工作时间偷个懒写两篇文章。
将相机或相册图片上传到服务器
先看看最常见的图片上传,也可以选择跳过,后面有直接的封装方法
在实际开发中,图片上传是很常见的功能,比如和朋友圈一样发布一条动态要添加几张图片,或者上传用户头像什么的,这里就介绍如何通过第三方库Alamofire进行图片上传(这里使用的是Swift,下文更新了Swift3、Alamofire4.5.0的代码版本,OC可以用AFNetworking)。
当我们上传图片通常还需要带参数,Alamofire不像AF一样具有封装好的带参数上传图片的方法,但是可以通过其他方法拼接参数,代码中会有相应注释。
如下图,我已经写好了调用相机和相册的界面,如果不会使用相机相册,请看我之前写过的一篇文章:http://www.jianshu.com/p/ab98f2fe2734
我分别给取消按钮,拍照按钮,相册按钮设置了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
}
}
做了上述点击事件后,点击相机拍照后或者相册进行选择后就可得到照片选择器
选择完成我们就可以用相机协议(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)
//失败要干什么
}
})
swift文件服务器,Swift3一行代码将各种类型文件上传到服务器相关推荐
- php文件上传绕过mime类型,文件上传限制绕过技巧
严正声明:本文仅限于技术讨论,严禁用于其他用途. 简介 文件上传漏洞是web安全中经常利用到的一种漏洞形式.一些web应用程序中允许上传图片,文本或者其他资源到指定的位置,文件上传漏洞就是利用这些可以 ...
- bottle 文件服务器,python bottle 框架基础教程:文件上传 | linux系统运维
文件上传,需要注意的是前端html的form表单中,要添加 enctype="multipart/form-data"属性,否则无法上传文件.在后端,用request.files方 ...
- 【Java报错】MultipartFile 类型文件上传 Current request is not a multipart request 问题处理(postman添加MultipartFile)
1. 问题描述 一个正常的Excel文档上传并导入其数据的接口开发,首先出现问题的是 Doc 文档,我使用的是: <dependency><groupId>com.github ...
- hadoop上传文件java_hadoop入门之通过java代码实现将本地文件上传到hadoop的文件系统...
第一步:首先搭建java的编译环境.创建一个Java Project工程,名为upload. 第二步:选中所需的Jar包. 选中JRE System Library 选择BuildPath Confi ...
- 文件上传至服务器cpu,文件服务器构建指南
处理器篇 再说一次,文件服务器的主要用途是存储,而不是处理能力,也不是在游戏中获得很高的帧速率.就家庭文件服务器而言,包括处理器在内的其他所有部件都应该让位于硬盘.机箱和电源.重申一下,文件服务器不需 ...
- postman代码没有问题,但是文件上传失败
1. 问题分析 postman临时上传非工作区的文件是可以的,但是当你关掉postman再重启,postman会帮你记住选择的文件,但是永远没办法成功上传上去,原因是因为该文件不在工作区内. 2. 解 ...
- 上传文件的php代码,PHP实现大文件上传源代码
PHP实现大文件上传源代码 PHP 基础教程 PHP 是一种创建动态交互性站点的`强有力的服务器端脚本语言. PHP 是免费的,并且使用广泛. 以下是小编为大家搜索整理的PHP实现大文件上传源代码,希 ...
- python requests form data_Python requests模块 multipart/form-data类型文件上传
------WebKitFormBoundarytqaIYaLC4rpPRnpl Content-Disposition: form-data; name="isNew" 1 ...
- 文件上传到服务器 完整代码,上传文件到服务器 前端+后台代码
不是原创,但有必要记录一下,免得每次都找的很辛苦 html Select a File to Upload js function fileSelected() { var file = docume ...
最新文章
- 使用分层实现业务处理(二)
- 【备忘录】使用mongodb,报db.collection is not a function
- 网络爬虫中进行数据抓取
- Qt 图形视图框架中的事件处理和传播
- java getclass 相等_Java判断2个List集合是否相等(不考虑元素的顺序)
- 与ai计算机专业大学排名,全球大学计算机科学与人工智能排名:卡耐基梅隆大学居首...
- [家里蹲大学数学杂志]第036期泛函分析期末试题
- JavaFX UI控件教程(五)之Radio Button
- java hessian rmi_RMI,socket,rpc,hessian,http比较
- 在计算机发展的早期 计算机主要用于,全国网络统考《计算机应用基础》选择题复习...
- Java对象分配原理
- ArrayList的容量
- java 多态与重载的区别_java实现多态 方法的重写和重载的区别
- ECShop如何设置默认的配送方式和支付方式
- 华为进军美国受挫:竟被美运营商巨头临时放鸽子
- 【2019杭电多校第七场1006=HDU6651】Final Exam(思维转换)
- C语言UDP socket编程
- iphone12是双卡双待吗
- 你的MP3中不能缺少的231首歌
- 主播入门到精通培训实操手册全套资料(共300份)