Visual_Novel_iOS/crush/Crush/Src/Models/UploadModels.swift

338 lines
9.4 KiB
Swift
Raw Normal View History

2025-10-09 10:29:35 +00:00
//
// UploadModels.swift
// Crush
//
// Created by Leon on 2025/7/21.
//
import Foundation
import AWSS3
// MARK: - Protocols
protocol UploadPhotoCallBackProtocol {
func mm_uploadProgress(_ progress: Float)
func mm_uploadFailed()
func mm_uploadDone(_ remoteImageUrlString: String)
}
protocol UploadPhotoDelegate: AnyObject {
// func uploadFail()
// func uploadDone()
func uploadDoneWith(_ photo: UploadPhotoM)
func uploadFailWith(_ photo: UploadPhotoM)
func uploadProgress(_ progress: Float)
func imageCheck(_ photoM: UploadPhotoM, result: Bool)
// func imageIdentyReal(_ photo: UploadPhotoM, result: Bool)
// func imageIdentifyChild(_ photo: UploadPhotoM, result: Bool)
// func imageFullCheck(_ photo: UploadPhotoM, nfswCheck: Bool, realPersonCheck: Bool)
// func imageFullCheck(_ photo: UploadPhotoM, nfswCheck: Bool, childCheck: Bool)
}
protocol UploadModelDelegate: AnyObject {
func uploadFail()
func uploadDone()
func uploadDoneWith(_ photo: UploadModel)
func uploadFailWith(_ photo: UploadModel)
func uploadProgress(_ progress: Float)
}
// MARK: - UploadEntity
class UploadEntity: NSObject, UploadPhotoCallBackProtocol {
func mm_uploadProgress(_ progress: Float) {
}
func mm_uploadFailed() {
}
func mm_uploadDone(_ remoteImageUrlString: String) {
}
weak var utility: AWSS3TransferUtility?
var addThisItemTimeStamp: Int = 0
var uploadProgress: Float = 0.0
var isFailed: Bool = false
var isDone: Bool = false
var isUploading: Bool = false
}
// MARK: - UploadModel
class UploadModel: UploadEntity {
var fileData: Data?
var s3AuthData: S3AuthData?
///
var remoteImageUrlString: String?
var remoteFullPath: String?
weak var delegate: UploadModelDelegate?
func suffix() -> String {
return ".mp3"
}
func contentType() -> String {
return "audio/mp3"
}
func releaseS3Utility() {
if let utility = utility, let _ = s3AuthData?.fileName {
//#warning("Confirm")
//AWSS3TransferUtility.removeS3TransferUtility(forKey: fileName)
utility.cancelAll()
}
}
// MARK: - Setter Overrides
override var uploadProgress: Float {
get { super.uploadProgress }
set {
super.uploadProgress = newValue
delegate?.uploadProgress(newValue)
}
}
override var isDone: Bool {
get { super.isDone }
set {
super.isDone = newValue
delegate?.uploadDoneWith(self)
delegate?.uploadDone()
}
}
override var isFailed: Bool {
get { super.isFailed }
set {
super.isFailed = newValue
delegate?.uploadFailWith(self)
delegate?.uploadFail()
}
}
// MARK: - UploadPhotoCallBackProtocol
override func mm_uploadProgress(_ progress: Float) {
self.uploadProgress = progress
}
override func mm_uploadFailed() {
releaseS3Utility()
isFailed = true
isUploading = false
}
override func mm_uploadDone(_ remoteImageUrlString: String) {
releaseS3Utility()
self.remoteImageUrlString = remoteImageUrlString
isDone = true
isUploading = false
}
}
// MARK: - UploadPhotoM
class UploadPhotoM: UploadEntity {
weak var delegate: UploadPhotoDelegate?
// MARK: Data
var image: UIImage?{
didSet{
if image?.size.width ?? 0 > 0 && image?.size.height ?? 0 > 0{
imageSize = image!.pixelSize
}
}
}
var imageData: Data?
var bucketEnum: BucketS3Enum = .UNKNOW
var s3AuthData: S3AuthData?
///
var remoteImageUrlString: String?
///
var remoteFullPath: String?
var imageSize: CGSize = .zero
var suffixEnum: SuffixS3Enum = .jpeg
// MARK: Config
/// -- Config: Default true:
var isAutoCheckImage: Bool = true
var isHideCheckToast: Bool = false
// MARK: State
private(set) var imageCheckIsViolation: Bool = false
/// Default false
private(set) var imageChecked: Bool = false
private(set) var isOverSizeLimmit: Bool = false
private(set) var errorMsg: String?
var imageFrame: CGRect = .zero
var isEditMode: Bool = false
// MARK: Inner methods
/// true: delegate(UploadPhotoDelegate) CloudStorageblock
var banCheckImageInDelegateMethod: Bool = false
override init() {
super.init()
suffixEnum = .jpeg
}
// MARK: - Public Methods
func getFullUrlString() -> String {
if let fullUrl = remoteFullPath, fullUrl.count > 0 {
return fullUrl
}else if let remoteImageFull = remoteImageUrlString{
return remoteImageFull // .fullUrlFromRelativePath //
}
return ""
}
func setupValidImageUrl(url: String?){
guard let imgUrl = url else{return}
remoteFullPath = imgUrl
isDone = true
imageChecked = true
addThisItemTimeStamp = Date().timeStamp
}
/// block false
func checkImageOK(_ block: ((Bool) -> Void)? = nil) {
guard let tempPath = remoteImageUrlString, tempPath.isNotBlank else {
assert(false)
block?(false)
return
}
OssProvider.request(.nsfwCheck(fileFullPath: tempPath, s3BucketEnum: bucketEnum.rawValue), modelType: Bool.self) {[weak self] result in
guard let `self` = self else {
return
}
self.isUploading = false
switch result {
case let .success(checkResult):
self.imageChecked = true
//self.realateUrlAdpatEPalAddSlash(add: true)
let nsfw = checkResult ?? true
let imgOk = !nsfw
self.delegate?.imageCheck(self, result: imgOk)
block?(imgOk)
case let .failure(error):
switch error {
case let .serviceError(code, msg):
if code == .imageCheckFailed{
self.imageChecked = true
self.imageCheckIsViolation = true
self.errorMsg = msg
self.delegate?.imageCheck(self, result: false)
}else{
self.imageCheckIsViolation = false
self.isFailed = true
self.isDone = false
self.delegate?.imageCheck(self, result: false)
}
default:
break
}
block?(false)
}
}
}
func contentType() -> String {
switch suffixEnum {
case .gif: return "image/gif"
case .png: return "image/png"
default: return "image/jpeg"
}
}
func releaseS3Utility() {
if let utility = utility {
//AWSS3TransferUtility.removeS3TransferUtility(forKey: fileName)
utility.cancelAll()
}
}
func setupPhotoOversizeLimmit() {
isOverSizeLimmit = true
}
func setupErrorMsg(_ msg: String) {
errorMsg = msg
}
// MARK: - Setter Overrides
override var uploadProgress: Float {
get { super.uploadProgress }
set {
super.uploadProgress = newValue
delegate?.uploadProgress(newValue)
}
}
override var isDone: Bool {
get { super.isDone }
set {
super.isDone = newValue
delegate?.uploadDoneWith(self)
// delegate?.uploadDone()
}
}
override var isFailed: Bool {
get { super.isFailed }
set {
super.isFailed = newValue
delegate?.uploadFailWith(self)
// delegate?.uploadFail()
}
}
// MARK: - UploadPhotoCallBackProtocol
override func mm_uploadProgress(_ progress: Float) {
self.uploadProgress = progress
}
override func mm_uploadFailed() {
releaseS3Utility()
isFailed = true
isUploading = false
}
override func mm_uploadDone(_ remoteImageUrlString: String) {
releaseS3Utility()
self.remoteImageUrlString = remoteImageUrlString
isDone = true
if isAutoCheckImage {
if !banCheckImageInDelegateMethod {
checkImageOK(nil)
}
} else {
isUploading = false
realateUrlAdpatEPalAddSlash(add: true)
}
}
// MARK: - Helper
@discardableResult
private func realateUrlAdpatEPalAddSlash(add: Bool) -> String {
var url = remoteImageUrlString ?? ""
if add {
if !url.isEmpty && !url.hasPrefix("/") {
url = "/\(url)"
}
} else {
if !url.isEmpty && url.hasPrefix("/") {
url.removeFirst()
}
}
remoteImageUrlString = url
return url
}
}