objects = {
/* Begin PBXBuildFile section */
+ 1811885B2C1BE80B00C23FAB /* 1.pcm in Resources */ = {isa = PBXBuildFile; fileRef = 181188592C1BE80B00C23FAB /* 1.pcm */; };
18204BD42C193F9A00F94E69 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18204BD32C193F9A00F94E69 /* AppDelegate.swift */; };
18204BD62C193F9A00F94E69 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18204BD52C193F9A00F94E69 /* SceneDelegate.swift */; };
18204BD82C193F9A00F94E69 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18204BD72C193F9A00F94E69 /* ViewController.swift */; };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 181188592C1BE80B00C23FAB /* 1.pcm */ = {isa = PBXFileReference; lastKnownFileType = file; path = 1.pcm; sourceTree = "<group>"; };
18204BD02C193F9A00F94E69 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
18204BD32C193F9A00F94E69 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
18204BD52C193F9A00F94E69 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 181188582C1BE80B00C23FAB /* Resource */ = {
+ isa = PBXGroup;
+ children = (
+ 181188592C1BE80B00C23FAB /* 1.pcm */,
+ );
+ path = Resource;
+ sourceTree = "<group>";
+ };
18204BC72C193F9A00F94E69 = {
isa = PBXGroup;
children = (
18204BD22C193F9A00F94E69 /* Example */ = {
isa = PBXGroup;
children = (
+ 181188582C1BE80B00C23FAB /* Resource */,
18204BD32C193F9A00F94E69 /* AppDelegate.swift */,
18204BD52C193F9A00F94E69 /* SceneDelegate.swift */,
18204BD72C193F9A00F94E69 /* ViewController.swift */,
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 1811885B2C1BE80B00C23FAB /* 1.pcm in Resources */,
18204BE02C193F9D00F94E69 /* LaunchScreen.storyboard in Resources */,
18204BDD2C193F9D00F94E69 /* Assets.xcassets in Resources */,
18204BDB2C193F9A00F94E69 /* Main.storyboard in Resources */,
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <subviews>
- <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZOn-PK-K8d">
- <rect key="frame" x="49" y="95" width="100" height="54"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <state key="normal" title="Button"/>
- <buttonConfiguration key="configuration" style="gray" title="register">
- <backgroundConfiguration key="background"/>
- </buttonConfiguration>
- <connections>
- <action selector="registerAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="MjA-mA-eXX"/>
- </connections>
- </button>
- <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Iwj-0L-6nd">
- <rect key="frame" x="259" y="170" width="100" height="54"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <state key="normal" title="Button"/>
- <buttonConfiguration key="configuration" style="gray" title="通用翻译">
- <backgroundConfiguration key="background"/>
- </buttonConfiguration>
- <connections>
- <action selector="tranlateAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="r2v-DR-gSa"/>
- </connections>
- </button>
- <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="McA-22-96t">
- <rect key="frame" x="206" y="95" width="100" height="54"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <state key="normal" title="Button"/>
- <buttonConfiguration key="configuration" style="gray" title="login">
- <backgroundConfiguration key="background"/>
- </buttonConfiguration>
- <connections>
- <action selector="loginAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="kRm-ly-flg"/>
- </connections>
- </button>
- <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6wR-pv-u1r">
- <rect key="frame" x="26" y="170" width="198" height="54"/>
- <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <state key="normal" title="Button"/>
- <buttonConfiguration key="configuration" style="gray" title="获取翻译支持语言列表">
- <backgroundConfiguration key="background"/>
- </buttonConfiguration>
- <connections>
- <action selector="getSupportLanguagesAction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="s8U-yk-Edk"/>
- </connections>
- </button>
- </subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
import UIKit
import MixSdk
-class ViewController: UIViewController {
-
+class ViewController: UIViewController{
+
+ let list:[(name:String,action:String)] = [
+ ("注册","registerAction"),
+ ("登录","loginAction"),
+
+ ("获取翻译支持的语言","getSupportLanguagesAction"),
+ ("通用翻译","tranlateAction"),
+
+ ("一句话识别","sentenceRecognizeAction"),
+ ("开始实时转写","startTransAction"),
+ ("结束实时转写","endTransAction"),
+
+ ("aigc 获取算法类型","aigcGetStyleAction"),
+ ("aigc 创建任务","aigcCreateTaskAction"),
+ ("aigc 查询任务状态","aigcGetResultAction")
+ ]
+
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
+ let tableView = UITableView(frame: CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height), style: .plain)
+ tableView.delegate = self
+ tableView.dataSource = self
+ tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
+ view.addSubview(tableView)
}
+}
- @IBAction func registerAction(_ sender: Any) {
+extension ViewController:UITableViewDelegate,UITableViewDataSource {
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return list.count
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
+ cell.textLabel?.text = list[indexPath.row].name
+
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ let data = list[indexPath.row]
+ let action = Selector(data.action)
+ self.perform(action)
+ }
+}
+
+extension ViewController{
+ @objc func registerAction() {
let sn = "MSCL1BKZ12105000042363"
let deviceId = "C0310000A57B"
let productKey = "ccvUoJOLbXn"
}
}
}
- @IBAction func loginAction(_ sender: Any) {
+ @objc func loginAction() {
let deviceId = "C0310000A57B"
let productKey = "ccvUoJOLbXn"
let secretKey = "nNRjkRpKTxvprGaW"
- let deviceSecret = "ZqqFHYeXf4xuv5jEfuHUE2hdMnoaegGi"
+ let deviceSecret = "LQWKSJTOxUjqJgpxWTzLYDGPdTeFr2hO"
MSManager.shared.auth.login(productKey: productKey, secretKey: secretKey, deviceId: deviceId, deviceSecrect: deviceSecret){ isSuccess,error in
if let err = error{
print("\(err)")
}
}
}
- @IBAction func tranlateAction(_ sender: Any) {
+}
+extension ViewController{
+ @objc func tranlateAction() {
MSManager.shared.translate.translate(lang: "zh", text: "Translate General"){text,error in
if let err = error{
print("\(err)")
}
}
}
- @IBAction func getSupportLanguagesAction(_ sender: Any) {
+ @objc func getSupportLanguagesAction() {
MSManager.shared.translate.getSupportLanguages { list, error in
if let err = error{
print("\(err)")
}
}
}
+ @objc func sentenceRecognizeAction() {
+ guard let path = Bundle.main.path(forResource: "1", ofType: "pcm") else {return}
+ MSManager.shared.asr.sentenceRecognize(filePath: path,format:"WAV",sample_rate:"16000",lang: "zh-cn") { text, error in
+ if let err = error{
+ print("\(err)")
+ }
+ else{
+ print(text ?? "")
+ }
+ }
+ }
+}
+extension ViewController{
+ @objc func aigcGetStyleAction() {
+ MSManager.shared.aigc.getStyle(type: 5) { list, error in
+ if let err = error{
+ print("\(err)")
+ }
+ else{
+ print(list ?? "")
+ }
+ }
+ }
+ @objc func aigcGetResultAction() {
+ MSManager.shared.aigc.getResult(taskId: "123"){ jsonString, error in
+ if let err = error{
+ print("\(err)")
+ }
+ else{
+ print(jsonString ?? "")
+ }
+ }
+ }
+ @objc func aigcCreateTaskAction() {
+ let task = MSAigcTask()
+ task.subject = "一只奔跑的猫" // type=5 参数不生效
+ task.url = "https://public-vigen-video.oss-cn-shanghai.aliyuncs.com/public/dashscope/test.png" // type=0 不需要提交url type=5 必须提交
+ task.type = 5 //0:⽂字⽣图,1: ⽂+图⽣图 5: 图⽣图(⻛格变换)
+ task.amount = 2 //⽣成的图⽚数量 type=5 参数不生效
+ task.height = 1024//⽣成的图⽚⾼度,type=1时需要是32的倍数。 type=5 参数不生效
+ task.width = 1024//⽣成的图⽚宽度,type=1时需要是32的倍数。 type=5 参数不生效
+ task.algorithm = "4" //算法id可⽤值⻅get-style
+
+ MSManager.shared.aigc.createTask(task){ taskId, error in
+ if let err = error{
+ print("\(err)")
+ }
+ else{
+ print(taskId ?? "")
+ }
+ }
+ }
}
+extension ViewController{
+ @objc func startTransAction(){
+
+ }
+ @objc func endTransAction(){
+
+ }
+}
181188452C1AC35F00C23FAB /* MSError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181188442C1AC35F00C23FAB /* MSError.swift */; };
181188472C1ACA6100C23FAB /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181188462C1ACA6100C23FAB /* String+MD5.swift */; };
1811884E2C1AEF0F00C23FAB /* MSTranslate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1811884D2C1AEF0F00C23FAB /* MSTranslate.swift */; };
+ 181188572C1BE24200C23FAB /* MSAsr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181188562C1BE24200C23FAB /* MSAsr.swift */; };
+ 18132AED2C1C1EA8002F6B52 /* MSTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18132AEC2C1C1EA8002F6B52 /* MSTool.swift */; };
+ 18132AEF2C1C25CC002F6B52 /* MSAigc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18132AEE2C1C25CC002F6B52 /* MSAigc.swift */; };
18204BBF2C193E3D00F94E69 /* MixSdk.h in Headers */ = {isa = PBXBuildFile; fileRef = 18204BBE2C193E3D00F94E69 /* MixSdk.h */; settings = {ATTRIBUTES = (Public, ); }; };
18204BC62C193E4B00F94E69 /* MSAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18204BC52C193E4B00F94E69 /* MSAuth.swift */; };
18204BF02C19457600F94E69 /* IBHttpManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18204BEF2C19457600F94E69 /* IBHttpManager.swift */; };
181188442C1AC35F00C23FAB /* MSError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSError.swift; sourceTree = "<group>"; };
181188462C1ACA6100C23FAB /* String+MD5.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+MD5.swift"; sourceTree = "<group>"; };
1811884D2C1AEF0F00C23FAB /* MSTranslate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSTranslate.swift; sourceTree = "<group>"; };
+ 181188562C1BE24200C23FAB /* MSAsr.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSAsr.swift; sourceTree = "<group>"; };
+ 18132AEC2C1C1EA8002F6B52 /* MSTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSTool.swift; sourceTree = "<group>"; };
+ 18132AEE2C1C25CC002F6B52 /* MSAigc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSAigc.swift; sourceTree = "<group>"; };
18204BBB2C193E3D00F94E69 /* MixSdk.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MixSdk.framework; sourceTree = BUILT_PRODUCTS_DIR; };
18204BBE2C193E3D00F94E69 /* MixSdk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MixSdk.h; sourceTree = "<group>"; };
18204BC52C193E4B00F94E69 /* MSAuth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSAuth.swift; sourceTree = "<group>"; };
181188372C1A8B5200C23FAB /* CRC16.swift */,
181188382C1A8B5200C23FAB /* LRC.swift */,
181188462C1ACA6100C23FAB /* String+MD5.swift */,
+ 18132AEC2C1C1EA8002F6B52 /* MSTool.swift */,
);
path = Tools;
sourceTree = "<group>";
1811882E2C1A89E600C23FAB /* MSManager.swift */,
18204BC52C193E4B00F94E69 /* MSAuth.swift */,
1811884D2C1AEF0F00C23FAB /* MSTranslate.swift */,
+ 181188562C1BE24200C23FAB /* MSAsr.swift */,
+ 18132AEE2C1C25CC002F6B52 /* MSAigc.swift */,
181188442C1AC35F00C23FAB /* MSError.swift */,
);
path = MixSdk;
buildActionMask = 2147483647;
files = (
18204BC62C193E4B00F94E69 /* MSAuth.swift in Sources */,
+ 18132AED2C1C1EA8002F6B52 /* MSTool.swift in Sources */,
181188472C1ACA6100C23FAB /* String+MD5.swift in Sources */,
1811883F2C1A8B5200C23FAB /* CRC16.swift in Sources */,
181188452C1AC35F00C23FAB /* MSError.swift in Sources */,
1811883B2C1A8B5200C23FAB /* Logger.swift in Sources */,
+ 181188572C1BE24200C23FAB /* MSAsr.swift in Sources */,
18204BFD2C19488900F94E69 /* Operation.swift in Sources */,
1811883C2C1A8B5200C23FAB /* JSON.swift in Sources */,
181188402C1A8B5200C23FAB /* LRC.swift in Sources */,
1811882F2C1A89E600C23FAB /* MSManager.swift in Sources */,
18204BF02C19457600F94E69 /* IBHttpManager.swift in Sources */,
181188392C1A8B5200C23FAB /* Date.swift in Sources */,
+ 18132AEF2C1C25CC002F6B52 /* MSAigc.swift in Sources */,
1811883A2C1A8B5200C23FAB /* Any.swift in Sources */,
1811883E2C1A8B5200C23FAB /* UTF8.swift in Sources */,
1811884E2C1AEF0F00C23FAB /* MSTranslate.swift in Sources */,
--- /dev/null
+//
+// MSAigc.swift
+// MixSdk
+//
+// Created by incar on 2024/6/14.
+//
+
+import Foundation
+
+class MSAigcModel:Codable{
+ var status:Int = 0
+ var data:[MSAigcStyle] = []
+}
+
+
+/// aigc算法类型模型
+public class MSAigcStyle:Codable{
+ /// 名称
+ public var name = ""
+ /// 链接
+ public var url = ""
+ /// 代码
+ public var code = ""
+}
+
+/// aigc创建任务模型
+public class MSAigcTask:Codable{
+ /// 0:⽂字⽣图,1: ⽂+图⽣图 5: 图⽣图(⻛格变换)
+ public var type:Int = 0
+ /// 主题,type=5 参数不生效
+ public var subject:String?
+ /// type=0 不需要提交,url type=5 必须提交
+ public var url:String?
+ /// ⽣成的图⽚数量, type=5 参数不生效
+ public var amount:Int = 4
+ /// ⽣成的图⽚⾼度,type=1时需要是32的倍数。 type=5 参数不生效
+ public var height:Int = 320
+ /// ⽣成的图⽚宽度,type=1时需要是32的倍数。 type=5 参数不生效
+ public var width:Int = 320
+ /// 算法id可⽤值⻅get-style
+ public var algorithm:String = "auto"
+
+ public init() { }
+}
+
+
+public typealias MSAigcStyleCallBack = (_ list: [MSAigcStyle]?,_ error:MSError?) -> Void
+
+public typealias MSAigcTaskCallBack = (_ taskId: String?,_ error:MSError?) -> Void
+
+public typealias MSAigcQueryCallBack = (_ jsonString: String?,_ error:MSError?) -> Void
+
+public class MSAigc{
+ func getUrl(_ api:String)->String{
+ return "http://121.40.67.151:9099/" + api
+ }
+
+
+ /// 获取算法类型
+ /// - Parameters:
+ /// - type: 0:⽂字⽣图,1: ⽂+图⽣图 5:图⽣图(⻛格变换)
+ /// - completeHandler: 结果回调
+ public func getStyle(type:Int,completeHandler: @escaping MSAigcStyleCallBack){
+ if !MSManager.shared.auth.authorized {
+ completeHandler(nil,.unauthorised)
+ return
+ }
+ let url = getUrl("aigc/get-style")
+ let params = [
+ "type":type,
+ ]
+ Logger.log(url,params)
+
+ HTTP.POST(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ if let _ = response.error {
+ Logger.log(response.description)
+ completeHandler(nil,MSError.invalidRequest)
+ return
+ }
+ Logger.log(response.data.string ?? "")
+ guard let model = JSON.decode(MSAigcModel.self, from: response.data) else{
+ completeHandler(nil,MSError.parsingError)
+ return
+ }
+ if model.data.count > 0 {
+ completeHandler(model.data,nil)
+ }
+ else{
+ completeHandler(nil,MSError.reponseError(model.status,"获取失败"))
+ }
+ }
+ }
+
+
+ /// 查询任务状态
+ /// - Parameters:
+ /// - taskId: 任务id
+ /// - completeHandler: 结果回调
+ public func getResult(taskId:String,completeHandler: @escaping MSAigcQueryCallBack){
+ if !MSManager.shared.auth.authorized {
+ completeHandler(nil,.unauthorised)
+ return
+ }
+ let url = getUrl("aigc/get-result")
+ let params = [
+ "task_id":taskId,
+ ]
+ Logger.log(url,params)
+
+ HTTP.POST(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ if let _ = response.error {
+ Logger.log(response.description)
+ completeHandler(nil,MSError.invalidRequest)
+ return
+ }
+ Logger.log(response.data.string ?? "")
+ completeHandler(response.data.string,nil)
+ }
+ }
+
+
+ /// 创建任务
+ /// - Parameters:
+ /// - task: 任务参数
+ /// - completeHandler: 结果回调
+ public func createTask(_ task:MSAigcTask,completeHandler: @escaping MSAigcTaskCallBack){
+ if !MSManager.shared.auth.authorized {
+ completeHandler(nil,.unauthorised)
+ return
+ }
+ guard let params = task.encode?.jsonObject() as? [String:Any] else{
+ completeHandler(nil,MSError.invalidRequest)
+ return }
+
+ let url = getUrl("aigc/create-image")
+ Logger.log(url,params)
+
+ HTTP.POST(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ if let _ = response.error {
+ Logger.log(response.description)
+ completeHandler(nil,MSError.invalidRequest)
+ return
+ }
+ Logger.log(response.data.string ?? "")
+ guard let dict = response.data.jsonObject() as? NSDictionary else{
+ completeHandler(nil,MSError.parsingError)
+ return
+ }
+ if let status = dict["status"] as? Int,status == 0,let data = dict["data"] as? [String:Any], let task_id = data["task_id"] as? String{
+ completeHandler(task_id,nil)
+ }
+ else{
+ completeHandler(nil,MSError.reponseError(dict["status"] as? Int ?? 0, "请求失败"))
+ }
+ }
+ }
+}
--- /dev/null
+//
+// MSAsr.swift
+// MixSdk
+//
+// Created by incar on 2024/6/14.
+//
+
+import Foundation
+
+public typealias MSAsrCallBack = (_ text: String?,_ error:MSError?) -> Void
+
+public class MSAsr {
+
+ func getUrl()->String{
+ return "http://121.40.67.151:9099/asr/sentence-recognize?"
+ }
+
+ /// 一句话识别
+ /// - Parameters:
+ /// - filePath: 语音文件路径
+ /// - format: 语音格式,单声道(mono)16bit采样位数音频,包括无压缩的PCM、WAV、OPUS、AMR、SPEEX、MP3、AAC格式。
+ /// - sample_rate:采样率
+ /// - lang: zh-cn 中文/en-us 英文
+ /// - completeHandler: 结果回调
+ public func sentenceRecognize(filePath:String,format:String? = nil,sample_rate:String? = nil,lang:String? = nil,completeHandler: @escaping MSAsrCallBack){
+ if !MSManager.shared.auth.authorized {
+ completeHandler(nil,.unauthorised)
+ return
+ }
+ guard let fileData = MSTool.readFile(from: filePath) else {
+ completeHandler(nil,.invalidRequest)
+ return
+ }
+
+ var url = getUrl()
+ if let value = format{
+ url += "format=\(value)&"
+ }
+ if let value = lang{
+ url += "lang=\(value)&"
+ }
+ if let value = sample_rate{
+ url += "sample_rate=\(value)&"
+ }
+ Logger.log(url)
+
+ var request = URLRequest(url: URL(string:url)!)
+ request.httpMethod = "POST"
+ request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+ request.httpBody = fileData
+ let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
+ if let error = error {
+ completeHandler(nil,.invalidRequest)
+ Logger.log("Error: \(error)")
+ return
+ }
+ guard let data = data else {
+ completeHandler(nil,.invalidRequest)
+ return
+ }
+ Logger.log(data.string ?? "")
+ guard let dict = data.jsonObject() as? NSDictionary else{
+ completeHandler(nil,MSError.parsingError)
+ return
+ }
+ if let status = dict["status"] as? Int,status == 0,let data = dict["data"] as? [String:Any], let result = data["result"] as? String{
+ completeHandler(result,nil)
+ }
+ else{
+ completeHandler(nil,MSError.reponseError(dict["status"] as? Int ?? 0, "请求失败"))
+ }
+
+ }
+ task.resume()
+ }
+}
+
+
+
+
+
import Foundation
import CommonCrypto
-//class AuthResultModel:Codable{
-// var success = false
-// var msg = ""
-// var code = 0
-// var data:String? = ""
-//}
-
-public typealias MSRegisterCompleteHandler = (_ deviceSecret: String?,_ error:MSError?) -> Void
-public typealias MSLoginCompleteHandler = (_ isSuccess: Bool,_ error:MSError?) -> Void
+public typealias MSRegisterCallBack = (_ deviceSecret: String?,_ error:MSError?) -> Void
+public typealias MSLoginCallBack = (_ isSuccess: Bool,_ error:MSError?) -> Void
public class MSAuth {
- public var isAuth = false
+ public var authorized = true
func getUrl(_ api:String)->String{
return "https://app.api.thisiot.com/da/auth/" + api
/// - deviceId: 设备ID
/// - sn: SN号
/// - completeHandler: 结果回调
- public func register(productKey:String,secretKey:String,deviceId:String,sn:String,completeHandler: @escaping MSRegisterCompleteHandler){
+ public func register(productKey:String,secretKey:String,deviceId:String,sn:String,completeHandler: @escaping MSRegisterCallBack){
let timeStamp = "\(Int(Date().timeIntervalSince1970)*1000)"
let value = deviceId + sn + timeStamp + secretKey
let signValue = value.md5
/// - deviceId: 设备ID
/// - deviceSecrect: 注册返回的密码
/// - completeHandler: 结果回调
- public func login(productKey:String,secretKey:String,deviceId:String,deviceSecrect:String,completeHandler: @escaping MSLoginCompleteHandler){
+ public func login(productKey:String,secretKey:String,deviceId:String,deviceSecrect:String,completeHandler: @escaping MSLoginCallBack){
let timeStamp = "\(Int(Date().timeIntervalSince1970*1000))"
let value = deviceId + deviceSecrect + timeStamp + secretKey
let signValue = value.md5
return
}
if let result = dict["success"] as? Bool,result == true{
- self.isAuth = true
+ self.authorized = true
completeHandler(true,nil)
}
else{
didSet { Logger.isDebug = isDebug }
}
+
+ /// 鉴权
public var auth = MSAuth()
+ /// 翻译
public var translate = MSTranslate()
+
+ /// 语音识别
+ public var asr = MSAsr()
+
+ /// 人工智能AIGC
+ public var aigc = MSAigc()
}
var data:[MSSupportLanguage] = []
}
+/// 翻译支持的语言
public class MSSupportLanguage:Codable{
/// 中文名称
- var cn = ""
+ public var cn = ""
/// 英文名称
- var en = ""
+ public var en = ""
/// 代码
- var code = ""
+ public var code = ""
}
-public typealias MSTranslateCompleteHandler = (_ text: String?,_ error:MSError?) -> Void
-public typealias MSLanuageCompleteHandler = (_ list: [MSSupportLanguage]?,_ error:MSError?) -> Void
+public typealias MSTranslateCallBack = (_ text: String?,_ error:MSError?) -> Void
+public typealias MSLanuageCallBack = (_ list: [MSSupportLanguage]?,_ error:MSError?) -> Void
public class MSTranslate {
/// - lang: 语言
/// - text: 需要翻译的文字
/// - completeHandler: 结果回调
- func translate(lang:String,text:String,completeHandler: @escaping MSTranslateCompleteHandler){
+ func translate(lang:String,text:String,completeHandler: @escaping MSTranslateCallBack){
+ if !MSManager.shared.auth.authorized {
+ completeHandler(nil,.unauthorised)
+ return
+ }
let url = getUrl("general")
let params = [
"sl":"auto",
/// 获取支持的语言
/// - Parameter completeHandler: 结果回调
- func getSupportLanguages(completeHandler: @escaping MSLanuageCompleteHandler){
+ func getSupportLanguages(completeHandler: @escaping MSLanuageCallBack){
+ if !MSManager.shared.auth.authorized {
+ completeHandler(nil,.unauthorised)
+ return
+ }
let url = getUrl("languages")
Logger.log(url)
import Foundation
import Security
-open class SSLCert {
+ class SSLCert {
var certData: Data?
var key: SecKey?
- returns: a representation security object to be used with
*/
- public init(data: Data) {
+ init(data: Data) {
self.certData = data
}
/**
- Designated init for public keys
+ Designated init for keys
- - parameter key: is the public key to be used
+ - parameter key: is the key to be used
- returns: a representation security object to be used with
*/
- public init(key: SecKey) {
+ init(key: SecKey) {
self.key = key
}
}
-open class HTTPSecurity {
- open var validatedDN = true //should the domain name be validated?
+ class HTTPSecurity {
+ var validatedDN = true //should the domain name be validated?
var isReady = false //is the key processing done?
var certificates: [Data]? //the certificates
- var pubKeys: [SecKey]? //the public keys
- var usePublicKeys = false //use public keys or certificate validation?
+ var pubKeys: [SecKey]? //the keys
+ var useKeys = false //use keys or certificate validation?
/**
Use certs from main app bundle
- - parameter usePublicKeys: is to specific if the publicKeys or certificates should be used for SSL pinning validation
+ - parameter useKeys: is to specific if the Keys or certificates should be used for SSL pinning validation
- returns: a representation security object to be used with
*/
- public convenience init(usePublicKeys: Bool = false) {
+ convenience init(useKeys: Bool = false) {
let paths = Bundle.main.paths(forResourcesOfType: "cer", inDirectory: ".")
var collect = Array<SSLCert>()
for path in paths {
collect.append(SSLCert(data: d))
}
}
- self.init(certs:collect, usePublicKeys: usePublicKeys)
+ self.init(certs:collect, useKeys: useKeys)
}
/**
Designated init
- - parameter keys: is the certificates or public keys to use
- - parameter usePublicKeys: is to specific if the publicKeys or certificates should be used for SSL pinning validation
+ - parameter keys: is the certificates or keys to use
+ - parameter useKeys: is to specific if the Keys or certificates should be used for SSL pinning validation
- returns: a representation security object to be used with
*/
- public init(certs: [SSLCert], usePublicKeys: Bool) {
- self.usePublicKeys = usePublicKeys
+ init(certs: [SSLCert], useKeys: Bool) {
+ self.useKeys = useKeys
- if self.usePublicKeys {
+ if self.useKeys {
DispatchQueue.global().async {
var collect = Array<SecKey>()
for cert in certs {
if let data = cert.certData , cert.key == nil {
- cert.key = self.extractPublicKey(data)
+ cert.key = self.extractKey(data)
}
if let k = cert.key {
collect.append(k)
- returns: if the key was successfully validated
*/
- open func isValid(_ trust: SecTrust, domain: String?) -> Bool {
+ func isValid(_ trust: SecTrust, domain: String?) -> Bool {
var tries = 0
while(!self.isReady) {
policy = SecPolicyCreateBasicX509()
}
SecTrustSetPolicies(trust,policy)
- if self.usePublicKeys {
+ if self.useKeys {
if let keys = self.pubKeys {
var trustedCount = 0
- let serverPubKeys = publicKeyChainForTrust(trust)
+ let serverPubKeys = KeyChainForTrust(trust)
for serverKey in serverPubKeys as [AnyObject] {
for key in keys as [AnyObject] {
if serverKey.isEqual(key) {
}
/**
- Get the public key from a certificate data
+ Get the key from a certificate data
- - parameter data: is the certificate to pull the public key from
+ - parameter data: is the certificate to pull the key from
- - returns: a public key
+ - returns: a key
*/
- func extractPublicKey(_ data: Data) -> SecKey? {
+ func extractKey(_ data: Data) -> SecKey? {
let possibleCert = SecCertificateCreateWithData(nil,data as CFData)
if let cert = possibleCert {
- return extractPublicKeyFromCert(cert, policy: SecPolicyCreateBasicX509())
+ return extractKeyFromCert(cert, policy: SecPolicyCreateBasicX509())
}
return nil
}
/**
- Get the public key from a certificate
+ Get the key from a certificate
- - parameter data: is the certificate to pull the public key from
+ - parameter data: is the certificate to pull the key from
- - returns: a public key
+ - returns: a key
*/
- func extractPublicKeyFromCert(_ cert: SecCertificate, policy: SecPolicy) -> SecKey? {
+ func extractKeyFromCert(_ cert: SecCertificate, policy: SecPolicy) -> SecKey? {
var possibleTrust: SecTrust?
SecTrustCreateWithCertificates(cert, policy, &possibleTrust)
if let trust = possibleTrust {
var result: SecTrustResultType = SecTrustResultType(rawValue: UInt32(0))!
SecTrustEvaluate(trust, &result)
+// return SecTrustCopyKey(trust)
return SecTrustCopyPublicKey(trust)
+
}
return nil
}
}
/**
- Get the public key chain for the trust
+ Get the key chain for the trust
- - parameter trust: is the trust to lookup the certificate chain and extract the public keys
+ - parameter trust: is the trust to lookup the certificate chain and extract the keys
- - returns: the public keys from the certifcate chain for the trust
+ - returns: the keys from the certifcate chain for the trust
*/
- func publicKeyChainForTrust(_ trust: SecTrust) -> Array<SecKey> {
+ func KeyChainForTrust(_ trust: SecTrust) -> Array<SecKey> {
var collect = Array<SecKey>()
let policy = SecPolicyCreateBasicX509()
for i in 0 ..< SecTrustGetCertificateCount(trust) {
let cert = SecTrustGetCertificateAtIndex(trust,i)
- if let key = extractPublicKeyFromCert(cert!, policy: policy) {
+ if let key = extractKeyFromCert(cert!, policy: policy) {
collect.append(key)
}
}
/**
This protocol exist to allow easy and customizable swapping of a serializing format within an class methods of HTTP.
*/
-public protocol HTTPSerializeProtocol {
+ protocol HTTPSerializeProtocol {
/**
implement this protocol to support serializing parameters to the proper HTTP body or URL
/**
Standard HTTP encoding
*/
-public struct HTTPParameterSerializer: HTTPSerializeProtocol {
- public init() { }
- public func serialize(_ request: inout URLRequest, parameters: HTTPParameterProtocol) -> Error? {
+ struct HTTPParameterSerializer: HTTPSerializeProtocol {
+ init() { }
+ func serialize(_ request: inout URLRequest, parameters: HTTPParameterProtocol) -> Error? {
return request.appendParameters(parameters)
}
}
/**
Send the data as a JSON body
*/
-public struct JSONParameterSerializer: HTTPSerializeProtocol {
- public init() { }
- public func serialize(_ request: inout URLRequest, parameters: HTTPParameterProtocol) -> Error? {
+ struct JSONParameterSerializer: HTTPSerializeProtocol {
+ init() { }
+ func serialize(_ request: inout URLRequest, parameters: HTTPParameterProtocol) -> Error? {
return request.appendParametersAsJSON(parameters)
}
}
/**
All the things of an HTTP response
*/
-open class Response {
+ class Response {
/// The header values in HTTP response.
- open var headers: Dictionary<String,String>?
+ var headers: Dictionary<String,String>?
/// The mime type of the HTTP response.
- open var mimeType: String?
+ var mimeType: String?
/// The suggested filename for a downloaded file.
- open var suggestedFilename: String?
+ var suggestedFilename: String?
/// The body data of the HTTP response.
- open var data: Data {
+ var data: Data {
return collectData as Data
}
/// The status code of the HTTP response.
- open var statusCode: Int?
+ var statusCode: Int?
/// The URL of the HTTP response.
- open var URL: Foundation.URL?
+ var URL: Foundation.URL?
/// The Error of the HTTP response (if there was one).
- open var error: Error?
+ var error: Error?
///Returns the response as a string
- open var text: String? {
+ var text: String? {
return String(data: data, encoding: .utf8)
}
///get the description of the response
- open var description: String {
+ var description: String {
var buffer = ""
if let u = URL {
buffer += "URL:\n\(u)\n\n"
/**
The class that does the magic. Is a subclass of NSOperation so you can use it with operation queues or just a good ole HTTP request.
*/
-open class HTTP {
+ class HTTP {
/**
Get notified with a request finishes.
*/
- open var onFinish:((Response) -> Void)? {
+ var onFinish:((Response) -> Void)? {
didSet {
if let handler = onFinish {
DelegateManager.sharedInstance.addTask(task, completionHandler: { (response: Response) in
}
}
///This is for handling authenication
- open var auth:((URLAuthenticationChallenge) -> URLCredential?)? {
+ var auth:((URLAuthenticationChallenge) -> URLCredential?)? {
set {
guard let resp = DelegateManager.sharedInstance.responseForTask(task) else { return }
resp.auth = newValue
}
///This is for doing SSL pinning
- open var security: HTTPSecurity? {
+ var security: HTTPSecurity? {
set {
guard let resp = DelegateManager.sharedInstance.responseForTask(task) else { return }
resp.security = newValue
}
///This is for monitoring progress
- open var progress: ((Float) -> Void)? {
+ var progress: ((Float) -> Void)? {
set {
guard let resp = DelegateManager.sharedInstance.responseForTask(task) else { return }
resp.progressHandler = newValue
}
///This is for handling downloads
- open var downloadHandler: ((Response, URL) -> Void)? {
+ var downloadHandler: ((Response, URL) -> Void)? {
set {
guard let resp = DelegateManager.sharedInstance.responseForTask(task) else { return }
resp.downloadHandler = newValue
/**
creates a new HTTP request.
*/
- public init(_ req: URLRequest, session: URLSession = SharedSession.defaultSession, isDownload: Bool = false) {
+ init(_ req: URLRequest, session: URLSession = SharedSession.defaultSession, isDownload: Bool = false) {
if isDownload {
task = session.downloadTask(with: req)
} else {
/**
start/sends the HTTP task with a completionHandler. Use this when *NOT* using an NSOperationQueue.
*/
- open func run(_ completionHandler: ((Response) -> Void)? = nil) {
+ func run(_ completionHandler: ((Response) -> Void)? = nil) {
if let handler = completionHandler {
onFinish = handler
}
/**
Cancel the running task
*/
- open func cancel() {
+ func cancel() {
task.cancel()
}
/**
Class method to run a GET request that handles the URLRequest and parameter encoding for you.
*/
- @discardableResult open class func GET(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil,
+ @discardableResult class func GET(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil,
requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
return Run(url, method: .GET, parameters: parameters, headers: headers, requestSerializer: requestSerializer, completionHandler: completionHandler)
}
/**
Class method to run a HEAD request that handles the URLRequest and parameter encoding for you.
*/
- @discardableResult open class func HEAD(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
+ @discardableResult class func HEAD(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
return Run(url, method: .HEAD, parameters: parameters, headers: headers, requestSerializer: requestSerializer, completionHandler: completionHandler)
}
/**
Class method to run a DELETE request that handles the URLRequest and parameter encoding for you.
*/
- @discardableResult open class func DELETE(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
+ @discardableResult class func DELETE(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
return Run(url, method: .DELETE, parameters: parameters, headers: headers, requestSerializer: requestSerializer, completionHandler: completionHandler)
}
/**
Class method to run a POST request that handles the URLRequest and parameter encoding for you.
*/
- @discardableResult open class func POST(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
+ @discardableResult class func POST(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
return Run(url, method: .POST, parameters: parameters, headers: headers, requestSerializer: requestSerializer, completionHandler: completionHandler)
}
/**
Class method to run a PUT request that handles the URLRequest and parameter encoding for you.
*/
- @discardableResult open class func PUT(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil,
+ @discardableResult class func PUT(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil,
requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
return Run(url, method: .PUT, parameters: parameters, headers: headers, requestSerializer: requestSerializer, completionHandler: completionHandler)
}
/**
Class method to run a PUT request that handles the URLRequest and parameter encoding for you.
*/
- @discardableResult open class func PATCH(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
+ @discardableResult class func PATCH(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
return Run(url, method: .PATCH, parameters: parameters, headers: headers, requestSerializer: requestSerializer, completionHandler: completionHandler)
}
/**
Class method to create a Download request that handles the URLRequest and parameter encoding for you.
*/
- open class func Download(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil,
+ class func Download(_ url: String, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil,
requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completion:@escaping ((Response, URL) -> Void)) {
guard let task = HTTP.New(url, method: .GET, parameters: parameters, headers: headers, requestSerializer: requestSerializer) else {return}
task.downloadHandler = completion
/**
Class method to create a HTTP request that handles the URLRequest and parameter encoding for you.
*/
- open class func New(_ url: String, method: HTTPVerb, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
+ class func New(_ url: String, method: HTTPVerb, parameters: HTTPParameterProtocol? = nil, headers: [String:String]? = nil, requestSerializer: HTTPSerializeProtocol = HTTPParameterSerializer(), completionHandler: ((Response) -> Void)? = nil) -> HTTP? {
guard var req = URLRequest(urlString: url, headers: headers) else {
guard let handler = completionHandler else { return nil }
let resp = Response()
/**
Set the global auth handler
*/
- open class func globalAuth(_ handler: ((URLAuthenticationChallenge) -> URLCredential?)?) {
+ class func globalAuth(_ handler: ((URLAuthenticationChallenge) -> URLCredential?)?) {
DelegateManager.sharedInstance.auth = handler
}
/**
Set the global security handler
*/
- open class func globalSecurity(_ security: HTTPSecurity?) {
+ class func globalSecurity(_ security: HTTPSecurity?) {
DelegateManager.sharedInstance.security = security
}
/**
Set the global request handler
*/
- open class func globalRequest(_ handler: ((inout URLRequest) -> Void)?) {
+ class func globalRequest(_ handler: ((inout URLRequest) -> Void)?) {
DelegateManager.sharedInstance.requestHandler = handler
}
}
Absorb all the delegates methods of NSURLSession and forwards them to pretty closures.
This is basically the sin eater for NSURLSession.
*/
-public class DelegateManager: NSObject, URLSessionDataDelegate, URLSessionDownloadDelegate {
+ class DelegateManager: NSObject, URLSessionDataDelegate, URLSessionDownloadDelegate {
//the singleton to handle delegate needs of NSURLSession
static let sharedInstance = DelegateManager()
}
//handle getting data
- public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
+ func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
addResponseForTask(dataTask)
guard let resp = responseForTask(dataTask) else { return }
resp.collectData.append(data)
}
//handle task finishing
- public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
+ func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
guard let resp = responseForTask(task) else { return }
resp.error = error as NSError?
if let hresponse = task.response as? HTTPURLResponse {
}
//handle authenication
- public func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+ func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
var sec = security
var au = auth
if let resp = responseForTask(task) {
}
//upload progress
- public func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
+ func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
guard let resp = responseForTask(task) else { return }
progressHandler(resp, expectedLength: totalBytesExpectedToSend, currentLength: totalBytesSent)
}
//download progress
- public func urlSession(_ session: Foundation.URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
+ func urlSession(_ session: Foundation.URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
guard let resp = responseForTask(downloadTask) else { return }
progressHandler(resp, expectedLength: totalBytesExpectedToWrite, currentLength: totalBytesWritten)
}
//handle download task
- public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
+ func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
guard let resp = responseForTask(downloadTask) else { return }
guard let handler = resp.downloadHandler else { return }
handler(resp, location)
}
//handle progress
- public func progressHandler(_ response: Response, expectedLength: Int64, currentLength: Int64) {
+ func progressHandler(_ response: Response, expectedLength: Int64, currentLength: Int64) {
guard let handler = response.progressHandler else { return }
let slice = Float(1.0)/Float(expectedLength)
handler(slice*Float(currentLength))
/**
Handles providing singletons of NSURLSession.
*/
-public class SharedSession {
- public static let defaultSession = URLSession(configuration: URLSessionConfiguration.default,
+ class SharedSession {
+ static let defaultSession = URLSession(configuration: URLSessionConfiguration.default,
delegate: DelegateManager.sharedInstance, delegateQueue: nil)
static let ephemeralSession = URLSession(configuration: URLSessionConfiguration.ephemeral,
delegate: DelegateManager.sharedInstance, delegateQueue: nil)
/**
Bare bones queue to manage HTTP Requests
*/
-open class HTTPQueue {
- public var maxSimultaneousRequest = 5
+ class HTTPQueue {
+ var maxSimultaneousRequest = 5
var queue = [HTTP]()
let mutex = NSLock()
var activeReq = [Int: HTTP]()
var finishedHandler: (() -> Void)?
- public init(maxSimultaneousRequest: Int) {
+ init(maxSimultaneousRequest: Int) {
self.maxSimultaneousRequest = maxSimultaneousRequest
}
- open func add(request: URLRequest) {
+ func add(request: URLRequest) {
add(http: HTTP(request))
}
- open func add(http: HTTP) {
+ func add(http: HTTP) {
var doWork = false
mutex.lock()
queue.append(http)
}
}
- open func finished(queue: DispatchQueue = DispatchQueue.main, completionHandler: @escaping (() -> Void)) {
+ func finished(queue: DispatchQueue = DispatchQueue.main, completionHandler: @escaping (() -> Void)) {
finishedHandler = completionHandler
}
/**
The standard HTTP Verbs
*/
-public enum HTTPVerb: String {
+ enum HTTPVerb: String {
case GET = "GET"
case POST = "POST"
case PUT = "PUT"
/**
This is used to create key/value pairs of the parameters
*/
-public struct HTTPPair {
+ struct HTTPPair {
var key: String?
let storeVal: AnyObject
/**
This is super gross, but it is just an edge case, I'm willing to live with it
versus trying to handle such an rare need with more code and confusion
*/
-public class HTTPParameterProtocolSettings {
- public static var sendEmptyArray = false
+ class HTTPParameterProtocolSettings {
+ static var sendEmptyArray = false
}
/**
This protocol is used to make the dictionary and array serializable into key/value pairs.
*/
-public protocol HTTPParameterProtocol {
+ protocol HTTPParameterProtocol {
func createPairs(_ key: String?) -> [HTTPPair]
}
Support for the Dictionary type as an HTTPParameter.
*/
extension Dictionary: HTTPParameterProtocol {
- public func createPairs(_ key: String?) -> [HTTPPair] {
+ func createPairs(_ key: String?) -> [HTTPPair] {
var collect = [HTTPPair]()
for (k, v) in self {
if let nestedKey = k as? String {
*/
extension Array: HTTPParameterProtocol {
- public func createPairs(_ key: String?) -> [HTTPPair] {
+ func createPairs(_ key: String?) -> [HTTPPair] {
var collect = [HTTPPair]()
for v in self {
let useKey = key != nil ? "\(key!)[]" : key
Support for the Upload type as an HTTPParameter.
*/
extension Upload: HTTPParameterProtocol {
- public func createPairs(_ key: String?) -> Array<HTTPPair> {
+ func createPairs(_ key: String?) -> Array<HTTPPair> {
var collect = Array<HTTPPair>()
collect.append(HTTPPair(key: key, value: self))
return collect
Convenience init to allow init with a string.
-parameter urlString: The string representation of a URL to init with.
*/
- public init?(urlString: String, parameters: HTTPParameterProtocol? = nil, headers: [String: String]? = nil, cachePolicy: URLRequest.CachePolicy = .useProtocolCachePolicy, timeoutInterval: TimeInterval = 60) {
+ init?(urlString: String, parameters: HTTPParameterProtocol? = nil, headers: [String: String]? = nil, cachePolicy: URLRequest.CachePolicy = .useProtocolCachePolicy, timeoutInterval: TimeInterval = 60) {
if let url = URL(string: urlString) {
self.init(url: url)
} else {
/**
Convenience method to avoid having to use strings and allow using an enum
*/
- public var verb: HTTPVerb {
+ var verb: HTTPVerb {
set {
httpMethod = newValue.rawValue
}
If it contains a file it uses `multipart/form-data` for the content type.
-parameter parameters: The container (array or dictionary) to convert and append to the URL or Body
*/
- public mutating func appendParameters(_ parameters: HTTPParameterProtocol) -> Error? {
+ mutating func appendParameters(_ parameters: HTTPParameterProtocol) -> Error? {
if isURIParam() {
appendParametersAsQueryString(parameters)
} else if containsFile(parameters) {
append the parameters as a HTTP Query string. (e.g. domain.com?first=one&second=two)
-parameter parameters: The container (array or dictionary) to convert and append to the URL
*/
- public mutating func appendParametersAsQueryString(_ parameters: HTTPParameterProtocol) {
+ mutating func appendParametersAsQueryString(_ parameters: HTTPParameterProtocol) {
let queryString = parameters.createPairs(nil).map({ (pair) in
return pair.escapedValue
}).joined(separator: "&")
append the parameters as a url encoded string. (e.g. in the body of the request as: first=one&second=two)
-parameter parameters: The container (array or dictionary) to convert and append to the HTTP body
*/
- public mutating func appendParametersAsUrlEncoding(_ parameters: HTTPParameterProtocol) {
+ mutating func appendParametersAsUrlEncoding(_ parameters: HTTPParameterProtocol) {
if value(forHTTPHeaderField: contentTypeKey) == nil {
var contentStr = "application/x-www-form-urlencoded"
if let charset = CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(String.Encoding.utf8.rawValue)) {
append the parameters as a multpart form body. This is the type normally used for file uploads.
-parameter parameters: The container (array or dictionary) to convert and append to the HTTP body
*/
- public mutating func appendParametersAsMultiPartFormData(_ parameters: HTTPParameterProtocol) -> Error? {
+ mutating func appendParametersAsMultiPartFormData(_ parameters: HTTPParameterProtocol) -> Error? {
let boundary = "Boundary+\(arc4random())\(arc4random())"
if value(forHTTPHeaderField: contentTypeKey) == nil {
setValue("multipart/form-data; boundary=\(boundary)",
send the parameters as a body of JSON
-parameter parameters: The container (array or dictionary) to convert and append to the URL or Body
*/
- public mutating func appendParametersAsJSON(_ parameters: HTTPParameterProtocol) -> Error? {
+ mutating func appendParametersAsJSON(_ parameters: HTTPParameterProtocol) -> Error? {
if isURIParam() {
appendParametersAsQueryString(parameters)
} else {
/**
Check if the request requires the parameters to be appended to the URL
*/
- public func isURIParam() -> Bool {
+ func isURIParam() -> Bool {
if verb == .GET || verb == .HEAD || verb == .DELETE {
return true
}
check if the parameters contain a file object within them
-parameter parameters: The parameters to search through for an upload object
*/
- public func containsFile(_ parameters: HTTPParameterProtocol) -> Bool {
+ func containsFile(_ parameters: HTTPParameterProtocol) -> Bool {
for pair in parameters.createPairs(nil) {
if let _ = pair.upload {
return true
import Foundation
/// HTTP Status Code (RFC 2616)
-public enum HTTPStatusCode: Int {
+ enum HTTPStatusCode: Int {
case `continue` = 100,
switchingProtocols = 101
self = HTTPStatusCode(rawValue: statusCode) ?? .unknownStatus
}
- public var statusDescription: String {
+ var statusDescription: String {
get {
switch self {
case .continue:
/**
This is how to upload files in SwiftHTTP. The upload object represents a file to upload by either a data blob or a url (which it reads off disk).
*/
-open class Upload: NSObject, NSCoding {
+ class Upload: NSObject, NSCoding {
var fileUrl: URL? {
didSet {
getMimeType()
/**
Reads the data from disk or from memory. Throws an error if no data or file is found.
*/
- open func getData() -> (data: Data?, error: Error?) {
+ func getData() -> (data: Data?, error: Error?) {
if let d = data {
return (d, nil)
}
/**
Standard NSCoder support
*/
- open func encode(with aCoder: NSCoder) {
+ func encode(with aCoder: NSCoder) {
aCoder.encode(self.fileUrl, forKey: "fileUrl")
aCoder.encode(self.mimeType, forKey: "mimeType")
aCoder.encode(self.fileName, forKey: "fileName")
/**
Required for NSObject support (because of NSCoder, it would be a struct otherwise!)
*/
- public override init() {
+ override init() {
super.init()
}
- required public convenience init(coder aDecoder: NSCoder) {
+ required convenience init(coder aDecoder: NSCoder) {
self.init()
fileUrl = aDecoder.decodeObject(forKey: "fileUrl") as? URL
mimeType = aDecoder.decodeObject(forKey: "mimeType") as? String
-parameter fileUrl: The fileUrl is a standard url path to a file.
*/
- public convenience init(fileUrl: URL) {
+ convenience init(fileUrl: URL) {
self.init()
self.fileUrl = fileUrl
}
-parameter mimeType: The mimeType is just that. The mime type you would like the file to uploaded as.
*/
///upload a file from a a data blob. Must add a filename and mimeType as that can't be infered from the data
- public convenience init(data: Data, fileName: String, mimeType: String) {
+ convenience init(data: Data, fileName: String, mimeType: String) {
self.init()
self.data = data
self.fileName = fileName
--- /dev/null
+//
+// MSTool.swift
+// MixSdk
+//
+// Created by incar on 2024/6/14.
+//
+
+import Foundation
+
+class MSTool{
+ static func dataToJson(_ data:Data)->[String:Any]?{
+ do {
+ let jsonData = try JSONSerialization.jsonObject(with: data, options: .fragmentsAllowed)
+ return jsonData as? [String:Any]
+ } catch {
+ return nil
+ }
+ }
+ static func jsonToData(_ json:[String:Any])->Data?{
+ do {
+ let jsonData = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
+ return jsonData
+ } catch {
+ return nil
+ }
+ }
+
+ static func readFile(from path:String) ->Data?{
+ let fileURL = URL(fileURLWithPath: path)
+ do {
+ let data = try Data(contentsOf:fileURL)
+ return data
+ } catch {
+ return nil
+ }
+ }
+}