123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- //
- // TSNetWork+Business.swift
- // AIEmoji
- //
- // Created by 100Years on 2025/1/16.
- //
- /// 基础 URL(根据需求修改)
- private let baseURL = "http://ai.100yearslater.com"
- private let baseChinaURL = "http://ai.100yearslater100.com"
- import Alamofire
- enum TSNeURLType:String {
-
- case imageEmoji = "/api/image/emoji" //文生emoji
- case actionInfo = "/api/action/info" //查询生成过程接口
- case chat = "/api/text/chat" //AI 对话接口
- case textPicCreate = "/api/image/create" //文生图
- case upload = "/api/upload" //上传图片
- case imageRewrite = "/api/image/rewrite" //图生图
- case imageToImageStyle = "/api/ops/aichat-img2img-config" //图生图 风格列表
- case chatV2 = "/api/text/chat/v2" //AI 对话接口V2,扩展了 DeepSeek 深度思考
-
- case config = "/api/ops/aichat-config" //App配置
-
- case changeAge = "/api/image/change-age" //换年龄
- case subscriptionApple = "/api/subscription/apple" //苹果订阅
- case changeEmotion = "/api/image/change-emotion" //更换表情
- case changeHair = "/api/image/change-hair" //更换头发
- case imageRestore = "/api/image/restore" //老照片修复
- case eyeOpen = "/api/image/eye-open" //睁眼
- case pretty = "/api/image/pretty" //美容
- case photoAnimation = "/api/image/animation" //照片变活
- case photoExpand = "/api/image/outpaint" //照片扩展
-
- case overResolution = "/api/image/over-resolution" //图片超分辨率
- case changeClothes = "/api/image/change-clothes" //换衣服
-
- func getUrlString() -> String {
- if Locale.current.identifier.contains("_CN") {//中国区
- return baseChinaURL + self.rawValue
- }else{
- return baseURL + self.rawValue
- }
- }
- }
- //let kGenerateFailed:String = "Failed to generate, please try later".localized
- let kGenerateFailed:String = "Sorry there was a slight problem with the image processing, please try again later.".localized
- enum TSNetWorkCode : Int {
- case success = 200
- case fail = 0 //通用错误
- case textSensitive = -10003 //文生图敏感错误
- case imageSensitive = -10004 //图生图敏感错误
- case networkError = -1005 //网络错误
-
-
- var errorMsg:String {
- switch self {
- case .textSensitive,.imageSensitive:
- return "Your photo may contain nudity, gore or violence that does not comply with the health policy, please replace the photo and try again.".localized
- case .networkError:
- return "No network, please check your network and try again.".localized
- default:
- return "Sorry there was a slight problem with the image processing, please try again later.".localized
- }
-
- }
-
- //获取生成错误 code 对应的文案
- static func errorMsg(code:Int)->String{
- let netCode = TSNetWorkCode(rawValue: code) ?? .fail
- return netCode.errorMsg
- }
- //敏感错误
- static func sensitiveError(code:Int)->Bool{
- let netCode = TSNetWorkCode(rawValue: code)
- switch netCode {
- case .textSensitive,.imageSensitive:
- return true
- default:
- return false
- }
- }
-
- //网络错误错误
- static func networkError(code:Int)->Bool{
- let netCode = TSNetWorkCode(rawValue: code)
- switch netCode {
- case .networkError:
- return true
- default:
- return false
- }
- }
-
- //网络错误错误
- static func getErrorCode(_ error: Error) -> Int {
- if let urlError = error as? URLError {
- switch urlError.code {
- case .notConnectedToInternet, .networkConnectionLost:
- return TSNetWorkCode.networkError.rawValue
- default:
- return urlError.code.rawValue
- }
- }
- return 0
- }
- //获取生成错误 code 对应的文案
- static func getGeneratorStyle(code:Int)->TSGeneratorView.Style{
- let netCode = TSNetWorkCode(rawValue: code)
- switch netCode {
- case .textSensitive,.imageSensitive:
- return TSGeneratorView.Style.sensitiveError
- case .networkError:
- return TSGeneratorView.Style.netWorkError
- default:
- return TSGeneratorView.Style.generalError
- }
- }
- }
- extension Error {
-
- var tsCode:Int {
- if let error = self as? AFError, let underlyingError = error.underlyingError as? URLError {
- switch underlyingError.code {
- case .notConnectedToInternet, .networkConnectionLost,.timedOut:
- return TSNetWorkCode.networkError.rawValue
- default:
- return underlyingError.code.rawValue
- }
- }else
- if let urlError = self as? URLError {
- switch urlError.code {
- case .notConnectedToInternet, .networkConnectionLost,.timedOut:
- return TSNetWorkCode.networkError.rawValue
- default:
- return urlError.code.rawValue
- }
- }
- return 0
- }
-
- var tsDesc:String {
- return TSNetWorkCode.errorMsg(code: tsCode)
- }
- }
- func getUserInfoJsonString()->[String:Any] {
- let uuid: String
- let uuidUdKey = "my_UUID"
- if let saved = UserDefaults.standard.string(forKey: uuidUdKey),
- !saved.isEmpty {
- uuid = saved
- } else {
- let newUuid = UUID().uuidString
- UserDefaults.standard.set(newUuid, forKey: uuidUdKey)
- UserDefaults.standard.synchronize()
- uuid = newUuid
- }
-
- let dic:[String:Any] = [
- "device":UIDevice.current.modelName,
- "deviceId":uuid,
- "iosVersion":UIDevice.current.systemVersion,
- "appVersion":appShortVersion(),
- "subscriptionStatus":kPurchaseDefault.isVip ? "active" : "fallow",
- ]
- return dic
- }
- func getLanguageCode()->String{
- if Locale.current.identifier.contains("zh-Hant"){
- return "zh-Hant"
- }
- if let languageCode = Locale.current.languageCode {
- // print("当前设备语言简写: \(languageCode)") // 输出如 "en", "ja", "zh" 等
- return languageCode
- }
- return "en"
- }
- extension TSNetworkManager {
-
- /// 通用 get 请求
- func get<T: TSBaseModel>(
- urlType: TSNeURLType,
- parameters: [String: Any]? = nil,
- responseType: T.Type? = nil,
- completion: @escaping (Result<Any, Error>) -> Void
- ) -> Request {
- let urlString = urlType.getUrlString()
- return request(method: .get, urlString: urlString, parameters:parameters) { result in
- completion(result)
- }
- }
- /// 通用 POST 请求
- /// - Parameters:
- /// - endpoint: 接口路径
- /// - parameters: 请求参数
- /// - responseType: 响应数据模型(可选)
- /// - completion: 请求完成的回调
- func post<T: TSBaseModel>(
- urlType: TSNeURLType,
- parameters: [String: Any]? = nil,
- responseType: T.Type? = nil,
- completion: @escaping (Result<Any, Error>) -> Void
- ) -> Request {
- let urlString = urlType.getUrlString()
- return request(method: .post, urlString: urlString, parameters:parameters) { result in
- completion(result)
- }
- }
-
- /// 通用 POST Stream 请求
- /// - Parameters:
- /// - endpoint: 接口路径
- /// - parameters: 请求参数
- /// - responseType: 响应数据模型(可选)
- /// - completion: 请求完成的回调
- func postStream<T: TSBaseModel>(
- urlType: TSNeURLType,
- parameters: [String: Any]? = nil,
- responseType: T.Type? = nil,
- streamHandler:@escaping (String) -> Void,
- completion: @escaping (Result<Any, Error>) -> Void
- ) -> Request?{
- let urlString = urlType.getUrlString()
- let streamRequest = postStreamRequest(urlString: urlString, parameters: parameters, streamHandler: streamHandler, completion: completion)
- return streamRequest
- }
-
- /// 上传多个 Data 数据
- /// - Parameters:
- /// - urlType: TSNeURLType
- /// - dataArray: Data 数组,每个元素是一个字典,包含 Data 和字段名
- /// - parameters: 其他参数(可选)
- /// - headers: 自定义请求头(可选)
- /// - completion: 完成回调,返回结果或错误
- func uploadData<T: TSBaseModel>(
- urlType: TSNeURLType,
- dataArray: [[String: Any]], // Data 数组,每个元素包含 Data 和字段名
- parameters: [String: Any]? = nil,
- responseType: T.Type? = nil,
- progressHandler: @escaping (Float) -> Void, // 上传进度回调
- completion: @escaping (Result<Any, Error>) -> Void
- ) -> Request?{
- let urlString = urlType.getUrlString()
- let request = uploadData(urlString: urlString,dataArray:dataArray, parameters: parameters, progressHandler: { progress in
- progressHandler(Float(progress.fractionCompleted))
- },completion: completion)
- return request
- }
-
- func downloadFile(
- urlString: String,
- to destination: URL,
- progressHandler: ((Double) -> Void)? = nil,
- completion: @escaping (URL?, Error?) -> Void
- ) -> DownloadRequest? {
- let request = self.downloadFile(
- urlString: urlString,
- to: destination,
- progressHandler: { progress in
- print("下载进度: \(progress * 100)%")
- progressHandler?(progress)
- },
- completion: { result in
- switch result {
- case .success(let fileURL):
- dePrint("下载完成,文件保存在: \(fileURL.path)")
- completion(fileURL,nil)
- case .failure(let error):
- dePrint("下载失败: \(error.localizedDescription)")
- completion(nil,error)
- }
- }
- )
- return request
- }
- }
- extension TSNetworkManager {
-
- func uploadImage(
- upLoadImage:UIImage,
- maxKb:Int,
- progressHandler: @escaping (Float) -> Void, // 上传进度回调
- completion: @escaping (Any?, Error?) -> Void)
- -> Request?{
-
- guard let imageData = TSImageCompress.compressImageToTargetSize(upLoadImage, targetSizeKB: maxKb, preserveTransparency: false) else {
- completion(nil,NSError(domain: "image nil", code: 0))
- return nil
- }
-
- var dataArray:[[String:Any]] = []
- if upLoadImage.hasAlphaChannel(){
- dataArray = [
- ["data": imageData,
- "fieldName": "file", // 字段名
- "fileName": "image.png", // 文件名
- "mimeType": "image/png" // MIME 类型
- ]
- ]
- }else {
- dataArray = [
- ["data": imageData,
- "fieldName": "file", // 字段名
- "fileName": "image.jpeg", // 文件名
- "mimeType": "image/jpeg" // MIME 类型
- ]
- ]
- }
- return TSNetworkShared.uploadData(
- urlType: .upload,
- dataArray: dataArray,
- progressHandler: { progress in
- progressHandler(progress)
- },completion: { [weak self] result in
- guard let self = self else { return }
- switch result {
- case .success(let data):
- if let dataDict = kNetWorkCodeSuccess(data: data),
- let picUrl = dataDict["result"] as? String{
- completion(picUrl,nil)
- }else{
- let error = NSError(domain: "Service exception", code: 0)
- completion(nil,error)
- }
- case .failure(let error):
- completion(nil,error)
- }
- })
- }
-
- }
|