Files
yingmeng-ios-switf/yinmeng-ios/HttpRequest/YMRequestX.swift
2024-02-21 21:30:13 +08:00

229 lines
6.8 KiB
Swift

//
// YMRequestX.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/2.
//
import Foundation
public struct YMRequestX {
/// Maps data received from the signal into a JSON object.
public static func mapJSON<T>(_ type: T.Type, named: String, forResource: String = "RxNetworks") -> T? {
guard let data = jsonData(named, forResource: forResource) else {
return nil
}
let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
return json as? T
}
/// Read json data
public static func jsonData(_ named: String, forResource: String = "RxNetworks") -> Data? {
let bundle: Bundle?
if let bundlePath = Bundle.main.path(forResource: forResource, ofType: "bundle") {
bundle = Bundle.init(path: bundlePath)
} else {
bundle = Bundle.main
}
guard let path = ["json", "JSON", "Json"].compactMap({
bundle?.path(forResource: named, ofType: $0)
}).first else {
return nil
}
let contentURL = URL(fileURLWithPath: path)
return try? Data(contentsOf: contentURL)
}
public static func toJSON(form value: Any, prettyPrint: Bool = false) -> String? {
guard JSONSerialization.isValidJSONObject(value) else {
return nil
}
var jsonData: Data? = nil
if prettyPrint {
jsonData = try? JSONSerialization.data(withJSONObject: value, options: [.prettyPrinted])
} else {
jsonData = try? JSONSerialization.data(withJSONObject: value, options: [])
}
guard let data = jsonData else { return nil }
return String(data: data ,encoding: .utf8)
}
public static func toDictionary(form json: String) -> [String : Any]? {
guard let jsonData = json.data(using: .utf8),
let object = try? JSONSerialization.jsonObject(with: jsonData, options: []),
let result = object as? [String : Any] else {
return nil
}
return result
}
public static func keyWindow() -> UIWindow? {
if #available(iOS 13.0, *) {
return UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }
.first(where: { $0 is UIWindowScene })
.flatMap({ $0 as? UIWindowScene })?.windows
.first(where: \.isKeyWindow)
} else {
return UIApplication.shared.keyWindow
}
}
public static func topViewController() -> UIViewController? {
let window = UIApplication.shared.delegate?.window
guard window != nil, let rootViewController = window?!.rootViewController else {
return nil
}
return self.getTopViewController(controller: rootViewController)
}
public static func getTopViewController(controller: UIViewController) -> UIViewController {
if let presentedViewController = controller.presentedViewController {
return self.getTopViewController(controller: presentedViewController)
} else if let navigationController = controller as? UINavigationController {
if let topViewController = navigationController.topViewController {
return self.getTopViewController(controller: topViewController)
}
return navigationController
} else if let tabbarController = controller as? UITabBarController {
if let selectedViewController = tabbarController.selectedViewController {
return self.getTopViewController(controller: selectedViewController)
}
return tabbarController
} else {
return controller
}
}
}
// MARK: - HUD
extension YMRequestX {
/// HUD
public static func removeAllAtLevelStatusBarWindow() {
SharedDriver.shared.removeAllAtLevelStatusBarWindow()
}
/// HUD
public static func removeLoadingHUDs() {
SharedDriver.shared.removeLoadingHUDs()
}
public static func readHUD(key: String) -> LevelStatusBarWindowController? {
SharedDriver.shared.readHUD(key: key)
}
public static func saveHUD(key: String, window vc: LevelStatusBarWindowController) {
SharedDriver.shared.saveHUD(key: key, window: vc)
}
@discardableResult
public static func removeHUD(key: String?) -> LevelStatusBarWindowController? {
SharedDriver.shared.removeHUD(key: key)
}
}
// MARK: -
extension YMRequestX {
static func maxDelayTime(with plugins: APIPlugins) -> Double {
let times: [Double] = plugins.compactMap {
if let p = $0 as? PluginPropertiesable {
return p.delay
}
return 0.0
}
let maxTime = times.max() ?? 0.0
return maxTime
}
static func sortParametersToString(_ parameters: APIParameters?) -> String {
guard let params = parameters, !params.isEmpty else {
return ""
}
var paramString = "?"
let sorteds = params.sorted(by: { $0.key > $1.key })
for index in sorteds.indices {
paramString.append("\(sorteds[index].key)=\(sorteds[index].value)")
if index != sorteds.count - 1 { paramString.append("&") }
}
return paramString
}
static func requestLink(with target: TargetType, parameters: APIParameters? = nil) -> String {
let parameters: APIParameters? = parameters ?? {
if case .requestParameters(let parame, _) = target.task {
return parame
}
return nil
}()
let paramString = sortParametersToString(parameters)
return target.baseURL.absoluteString + target.path + paramString
}
static func toJSON(with response: Moya.Response) throws -> APISuccessJSON {
let response = try response.filterSuccessfulStatusCodes()
return try response.mapJSON()
}
static func loadingSuffix(key: SharedDriver.Key?) -> Bool {
guard let key = key else { return false }
if let suffix = key.components(separatedBy: "_").last, YMRequestConfig.loadingPluginNames.contains(suffix) {
return true
}
return false
}
static func setupPluginsAndKey(_ key: String, plugins: APIPlugins) -> APIPlugins {
var plugins = plugins
YMRequestX.setupBasePlugins(&plugins)
return plugins.map({
if var plugin = $0 as? PluginPropertiesable {
plugin.plugins = plugins
plugin.key = key + "_" + plugin.pluginName
return plugin
}
return $0
})
}
}
// MARK: -
extension YMRequestX {
///
static func setupBasePlugins(_ plugins: inout APIPlugins) {
var plugins_ = plugins
if let others = YMRequestConfig.basePlugins {
plugins_ += others
}
#if RXNETWORKS_PLUGINGS_INDICATOR
if NetworkConfig.addIndicator, !plugins_.contains(where: { $0 is NetworkIndicatorPlugin}) {
let Indicator = NetworkIndicatorPlugin.shared
plugins_.insert(Indicator, at: 0)
}
#endif
#if DEBUG && RXNETWORKS_PLUGINGS_DEBUGGING
if NetworkConfig.addDebugging, !plugins_.contains(where: { $0 is NetworkDebuggingPlugin}) {
let Debugging = NetworkDebuggingPlugin.init()
plugins_.append(Debugging)
}
#endif
plugins = plugins_
}
///
static func hasNetworkHttpHeaderPlugin(_ key: String) -> [String: String]? {
#if RXNETWORKS_PLUGINGS_HTTPHEADER
let plugins = SharedDriver.shared.readRequestPlugins(key)
if let p = plugins.first(where: { $0 is NetworkHttpHeaderPlugin }) {
return (p as? NetworkHttpHeaderPlugin)?.dictionary
}
#endif
return nil
}
}