/// 选择头像 private func selectHeadImage ( ) { let imagePickerVC = TZImagePickerController ( maxImagesCount : 1 , delegate : self ) imagePickerVC ? . modalTransitionStyle = . flipHorizontal imagePickerVC ? . modalPresentationStyle = . overCurrentContext imagePickerVC ? . showSelectBtn = false imagePickerVC ? . allowCrop = true imagePickerVC ? . cropRect = CGRect ( x : 0 , y : ( UIScreen . main . bounds . size . height - UIScreen . main . bounds . size . width ) / 2.0 , w : UIScreen . main . bounds . size . width , h : UIScreen . main . bounds . size . width ) imagePickerVC ? . allowPickingVideo = false imagePickerVC ? . allowPickingOriginalPhoto = false imagePickerVC ? . didFinishPickingPhotosHandle = { [ weak self ] photo , assets , isSelectOriginalPhoto in guard let photo = photo , let this = self , photo . count != 0 else { return } let img = photo . first this . getUploadUrl ( [ img ] ) self . presentVC ( imagePickerVC ! ) 获取图片上传路径数组,根据contentType数组后端返回一个上传路径的数组 HTTP Content-type 对照表:http://tools.jb51.net/table/http_content_type 接口返回: "message": null, "code": "00000", "data": ["https://cps-oss-prod.oss-cn-hangzhou.aliyuncs.com/cps/2022/04/13/16498338964949632?OSSAccessKeyId=LTAI5tJKUNiuZCSTyvTjAoAd&Expires=1649837586&Signature=n8J4a6%2BwVk2QXs7agUMzXrs979o%3D"] private func getUploadURL ( _ imageArr : [ UIImage ] ) { var typeArr : [ String ] = [ ] for img in imageArr { if let data = img . jpegData ( compressionQuality : 1 ) { let type = data . getImageFormat ( ) if type == . JPEG { typeArr . append ( "image/jpeg" ) } else if type == . PNG { typeArr . append ( "image/png" ) AlertHUD . show ( ) var params : [ String : Any ] = [ : ] params [ "contentType" ] = typeArr JRNetworkManager . shared . request ( CommonAPI . uploadUrl ( params ) , completed : { [ weak self ] ( result ) in AlertHUD . dismiss ( withDelay : 0.1 ) guard let this = self else { return } if let pathArr = result . object as ? [ String ] { this . imagesUpload ( imageArr : imageArr , pathArr : pathArr , contentTypeArr : typeArr ) } , failed : { ( status , error ) in AlertHUD . showText ( error ) /// 图片上传 private func imagesUpload ( imageArr : [ UIImage ] , pathArr : [ String ] , contentTypeArr : [ String ] ) { if imageArr . count == pathArr . count || imageArr . count == contentTypeArr . count { for ( index , img ) in imageArr . enumerated ( ) { let path = pathArr [ index ] JRNetworkManager . shared . aliyunUploadImage ( img , path , completed : { [ weak self ] ( result ) in if let photoPath = path . components ( separatedBy : "?" ) . first { self ? . editAvatar ( path : photoPath ) } , failed : { ( status , error ) in AlertHUD . showMsg ( "操作失败" ) /// 调用编辑头像接口 private func editAvatar ( path : String ) {

Alamofire使用put方式上传图片到阿里云

import Foundation
import Alamofire
import SwiftyJSON
enum NetworkStatus : String {
    case success = "00000"
    case networkError = "A0001"
    case otherError = "-1"
class JRNetworkManager: NSObject {
    static let shared = JRNetworkManager()
    typealias CompletedBlock = ((JSON) -> Void)
    typealias FailedBlock = ((NetworkStatus, String) -> Void)
      private override init() {
        super.init()
    /// 上传图片
    func aliyunUploadImage(_ image: UIImage, _ url: String, completed: @escaping CompletedBlock, failed: @escaping FailedBlock) {
        if let imageData = image.jpegData(compressionQuality: 0.5) {
            let reURL = url
            let stream = InputStream(data: imageData)
            var uploadHeaders: HTTPHeaders = [:]
            uploadHeaders["Content-Type"] = "image/jpeg"
            do {
                let newurl = try reURL.asURL()
                upload(stream, to: newurl , method: .put,headers: uploadHeaders)
                let tempData = JSON(["url":url])
                completed(tempData)
            } catch {
                failed(.otherError, "上传失败")
        } else {
            failed(.otherError, "上传失败")

根据Data获取文件的contentType

import Foundation
enum ImageFormat {
    case Unknow
    case JPEG
    case PNG
    case GIF
    case TIFF
    case WebP
    case HEIC
    case HEIF
extension Data {
    func getImageFormat() -> ImageFormat  {
        var buffer = [UInt8](repeating: 0, count: 1)
        self.copyBytes(to: &buffer, count: 1)
        switch buffer {
        case [0xFF]: return .JPEG
        case [0x89]: return .PNG
        case [0x47]: return .GIF
        case [0x49],[0x4D]: return .TIFF
        case [0x52] where self.count >= 12:
            if let str = String(data: self[0...11], encoding: .ascii), str.hasPrefix("RIFF"), str.hasSuffix("WEBP") {
                return .WebP
        case [0x00] where self.count >= 12:
            if let str = String(data: self[8...11], encoding: .ascii) {
                let HEICBitMaps = Set(["heic", "heis", "heix", "hevc", "hevx"])
                if HEICBitMaps.contains(str) {
                    return .HEIC
                let HEIFBitMaps = Set(["mif1", "msf1"])
                if HEIFBitMaps.contains(str) {
                    return .HEIF
        default: break;
        return .Unknow
                    项目中导入SwiftyJSON和Alamofirepod ‘SwiftyJSON’, ‘4.0.0’pod ‘Alamofire’, ‘4.9.0’选择图片,获取上传路径列表import UIKitclass UserInfoController: UIViewController {        /// 选择头像    private func selectHeadImage() {        let imagePickerVC = TZImagePickerControll
 RxAlamofire是包装,它围绕Swift 的优雅HTTP网络进行了。
将RxSwift包裹在Alamofire周围,使处理网络请求变得更加顺利和顺畅。 Alamofire是一个非常强大的框架,RxSwift添加了以简单有效的方式编写响应的功能。
 一个基本用法是(考虑一个简单的货币转换器):
 let formatter = NSNumberFormatter ()
formatter. numberStyle = . currencyStyle
formatter. currencyCode = " USD "
if let fromValue = NSNumberFormatter (). numberFromString ( self . fromTextField . text ! ) {
RxAlamofire. requestJSON (.
				
使用Alamofire上传图片到阿里OSS时会发现有的时候上传失败,原因是因为Alamofire拼接form-data的时候顺序会出错,所以需要自己使用URLRequest自己进行拼接就可以。 private let MultipartFormCRLF = "\r\n" private let MutlipartFormCRLFData = MultipartFormCRLF.data(using...
IOS的Alamofire5.4高版本上传图片 Alamofire框架上传图片是比较冷门的知识。经常性报错,也找不到相关解释,或者其他低版本的写法,令开发者很是头疼。低版本的写法,在5.4.4API已经过期了。不在适用。我只用高版本的软件和最新软件。其他一概不用的。 那么5.4.4版本的Alamofire高版本的图片上传如何去写。我用springBoot后端去接受图片的上传的。swift是最新语法。把传入进来的图片转化成二进制。具体url是否传参,以及成功后是否搞一个回调函数通知调用者。自己完善一下。通过点
let image = UIImage(named: "xxx") //将图片转化为JPEG类型的data 后面的参数是压缩比例 let jpegImage = UIImageJPEGRepresentation(image!, 0.5) //要传的参数(比如我们带用户的加密uid) let u... 上传调用方式如下: OSSClient oss = new OSSClient(context, endpoint, credentialProvider, conf); PutObjectResult putResult = oss.putO... public IHttpActionResult Upload() // return Ok(new ApiRequestResult { ErrorCode = 1, Data = 0, ErrorMessage = "Return result Is fasle" }); HttpFileC...
Package.swift 是在 Swift Package Manager 中使用的一个文件,它用来描述一个 Swift 包的元数据,包括包的名称、版本、依赖等信息。在使用 SPM 创建、管理和使用 Swift 包时,通常需要在项目目录中创建一个 Package.swift 文件。 一个简单的 Package.swift 文件可能包含如下内容: // swift-tools-version:5.3 import PackageDescription let package = Package( name: "MyPackage", platforms: [ .iOS(.v13), .macOS(.v10_15), .watchOS(.v6), .tvOS(.v13) products: [ .library( name: "MyPackage", targets: ["MyPackage"]), dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages which this package depends on. .target( name: "MyPackage", dependencies: []), .testTarget( name: "MyPackageTests", dependencies: ["MyPackage"]), 在 Package.swift 文件中配置完成后,使用 swift package 相关命令就可以管理这个包了, 如 swift package init, swift package update, swift package generate-xcodeproj等