Skip to content

Commit

Permalink
swift demo
Browse files Browse the repository at this point in the history
  • Loading branch information
YangSen-qn committed Jun 14, 2024
1 parent fd209d7 commit 2aea8fe
Show file tree
Hide file tree
Showing 16 changed files with 929 additions and 0 deletions.
436 changes: 436 additions & 0 deletions QiniuSwiftDemo/QiniuSwiftDemo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions QiniuSwiftDemo/QiniuSwiftDemo/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
13 changes: 13 additions & 0 deletions QiniuSwiftDemo/QiniuSwiftDemo/Config.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// Config.swift
// QiniuSwiftDemo
//
// Created by yangsen on 2024/6/13.
//

import Foundation

//struct Config: QNConfiguration {
// var token: String
//
//}
155 changes: 155 additions & 0 deletions QiniuSwiftDemo/QiniuSwiftDemo/ContentView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
//
// ContentView.swift
// QiniuSwiftDemo
//
// Created by yangsen on 2024/6/13.
//

import PopupView
import SwiftUI

private let kUploadBtnTextUpload = "上传"
private let kUploadBtnTextUploading = "上传..."

struct ContentView: View {

@State private var key = "iOS-Swift-Demo.png"
@State private var mimeType = ""
@State private var imagePickerSourceType = UIImagePickerController.SourceType.photoLibrary
@State private var showToast = false
@State private var toastText = ""
@State private var showAlert = false
@State private var showImagePicker = false
@State private var selectedImage: UIImage = UIImage(resource: ImageResource(name: "placeholder.png", bundle: .main))
@State private var btnTitle: String = kUploadBtnTextUpload
@State private var processValue: CGFloat = 0
@State private var isCancel = false

var body: some View {
NavigationView {
VStack {
HStack {
Text("Key:")
TextField("请输入文件保存的 Key(必需)", text: $key)
.foregroundColor(.gray)
}

HStack {
Text("MimeType:")
TextField("文件的 MimeType(可选)", text: $mimeType)
.foregroundColor(.gray)
}

Image(uiImage: selectedImage)
.resizable()
.scaledToFit()
.frame(minWidth: nil, idealWidth: nil, maxWidth: 0.8 * kScreenW,
minHeight: nil, idealHeight: nil, maxHeight: 0.4 * kScreenH,
alignment: .center)
.background(kBgColor)
.cornerRadius(3.0)
ProgressView(value: processValue * 0.01)
.frame(minWidth: nil, idealWidth: nil, maxWidth: 0.8 * kScreenW,
minHeight: nil, idealHeight: nil, maxHeight: 3,
alignment: .center)
.progressViewStyle(LinearProgressViewStyle(tint: kMainColor))
Spacer().frame(width: 10, height: 30, alignment: .center)
Button(btnTitle, action: upload)
.frame(width: 0.8 * kScreenW, height: 0.05 * kScreenH)
.background(kMainColor)
.foregroundColor(.white)
.cornerRadius(5)
.padding()
Button("取消", action: cancel)
.frame(width: 0.8 * kScreenW, height: 0.05 * kScreenH)
.background(kMainColor)
.foregroundColor(.white)
.cornerRadius(5)
.padding()
}.toolbar {
ToolbarItemGroup(placement: .navigationBarLeading) {
NavigationLink {
SettingView()
} label: {
Image(systemName: "gear")
}
}
ToolbarItemGroup(placement: .navigationBarTrailing) {
Button(action: {
showAlert = true
}) {
Image(systemName: "photo")
}
}
}.alert("图片来源", isPresented: $showAlert, actions: {
VStack {
Button("相机") {
showAlert = false
imagePickerSourceType = .camera
showImagePicker = true
}
.background(Color.white)
.foregroundColor(.purple)
Button("相册") {
showAlert = false
imagePickerSourceType = .photoLibrary
showImagePicker = true
}
.background(Color.white)
.foregroundColor(.purple)
Button("取消") { }
.background(Color.white)
.foregroundColor(.purple)
}.foregroundColor(kMainColor)
}).sheet(isPresented: $showImagePicker, content: {
ImagePicker(sourceType: imagePickerSourceType) { image in
guard let selectedImage = image else {
return
}

self.selectedImage = selectedImage
}
}).popup(isPresented: $showToast) {
VStack {
Text(toastText)
.padding(25)
.background(Color.init(white: 0.1))
.cornerRadius(3.0)
}
} customize: {
$0
.type(.toast)
.position(.center)
.autohideIn(5)
}
.padding()
.navigationTitle("七牛上传")
.foregroundColor(kMainColor)
}
}

private func cancel() {
isCancel = true
}

private func upload() {
Uploader.uploadImage(image: selectedImage, key: key, mimeType: mimeType) { send, total in
processValue = CGFloat(send) / CGFloat(total)
} cancel: {
return isCancel
} complete: { response, responseData in
btnTitle = kUploadBtnTextUpload
processValue = 0

isCancel = false
toastText = "response:\n\(String(describing: response))"
showToast = true
print("====== \(toastText)")
}
}
}


#Preview {
ContentView()
}
63 changes: 63 additions & 0 deletions QiniuSwiftDemo/QiniuSwiftDemo/ImagePicker.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// ImagePicker.swift
// QiniuSwiftDemo
//
// Created by yangsen on 2024/6/14.
//
import SwiftUI
import UIKit

struct ImagePicker: UIViewControllerRepresentable {

@Environment(\.presentationMode) private var presentationMode

let sourceType: UIImagePickerController.SourceType

let onImagePicked: (UIImage?) -> Void

final class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

@Binding private var presentationMode: PresentationMode

private let sourceType: UIImagePickerController.SourceType
private let onImagePicked: (UIImage?) -> Void

init(presentationMode: Binding<PresentationMode>,
sourceType: UIImagePickerController.SourceType,
onImagePicked: @escaping (UIImage?) -> Void) {

_presentationMode = presentationMode
self.sourceType = sourceType
self.onImagePicked = onImagePicked
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
let uiImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
onImagePicked(uiImage)

presentationMode.dismiss()
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
presentationMode.dismiss()
}

}

func makeCoordinator() -> Coordinator {
return Coordinator(presentationMode: presentationMode,
sourceType: sourceType,
onImagePicked: onImagePicked)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.sourceType = sourceType
picker.delegate = context.coordinator
return picker
}

func updateUIViewController(_ uiViewController: UIImagePickerController,
context: UIViewControllerRepresentableContext<ImagePicker>) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
12 changes: 12 additions & 0 deletions QiniuSwiftDemo/QiniuSwiftDemo/QiniuSwiftDemo-Bridging-Header.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// QiniuSwiftDemo-Bridging-Header.h
// QiniuSwiftDemo
//
// Created by yangsen on 2024/6/13.
//

#ifndef QiniuSwiftDemo_Bridging_Header_h
#define QiniuSwiftDemo_Bridging_Header_h


#endif /* QiniuSwiftDemo_Bridging_Header_h */
17 changes: 17 additions & 0 deletions QiniuSwiftDemo/QiniuSwiftDemo/QiniuSwiftDemoApp.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// QiniuSwiftDemoApp.swift
// QiniuSwiftDemo
//
// Created by yangsen on 2024/6/13.
//

import SwiftUI

@main
struct QiniuSwiftDemoApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
68 changes: 68 additions & 0 deletions QiniuSwiftDemo/QiniuSwiftDemo/QiniuUpload/Uploader.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// Uploader.swift
// QiniuSwiftDemo
//
// Created by yangsen on 2024/6/14.
//

import Foundation
import UIKit
import QiniuSDK

typealias UploadCancel = () -> Bool
typealias UploadProgressHander = (_ send: Int64, _ total: Int64) -> Void
typealias UploadCompleteHander = (_ response: QNResponseInfo?, _ responseData: [AnyHashable : Any]?) -> Void

struct Uploader {

static private var token = "dxVQk8gyk3WswArbNhdKIwmwibJ9nFsQhMNUmtIM:rJFJ8gG4elgOwiaDva00sGathQc=:eyJzY29wZSI6InRlc3QteXMiLCJkZWFkbGluZSI6MzQzNjcxODQ4NX0="
static private var uploadManager = QNUploadManager()

// 注意:此处和上传操作有并发问题
static func updateUploadConfig(config: QNConfiguration) {
uploadManager = QNUploadManager(configuration: config)
}


/// 上传
///
/// - Parameters:
/// - image: 上传的图片
/// - key: 图片保存 Key
/// - progress: 上传进度回调
/// - cancel: 取消回调,取消不能主动取消,SDK 内部在合适的时机会调用此函数,如果此函数返回为 true,则 SDK 内部上传 结束
/// - complete: 完成回调
static func uploadImage(image: UIImage,
key: String,
mimeType: String = "",
progress: UploadProgressHander? = nil,
cancel: UploadCancel? = nil,
complete: @escaping UploadCompleteHander) {

updateTokenIfNeeded()

let uploadOptions = QNUploadOption(mime: mimeType,
byteProgressHandler: { key, send, total in
progress?(send, total)
},
params: [AnyHashable : Any](),
checkCrc: true,
cancellationSignal: cancel)

// 上传
uploadManager?.put(image.pngData(),
key: key,
token: token,
complete: { reponse, key, responseData in
complete(reponse, responseData)
}, option: uploadOptions)

}

// 给 token 预留充分的时间,需要保证在文件上传结束之前 token 一直有效,比如:5min, 大文件可能需要更长,
// 在下发 token 时也给出有效的时间戳
static func updateTokenIfNeeded() {

}
}

Loading

0 comments on commit 2aea8fe

Please sign in to comment.