Skip to content

William-Weng/WWNetworking

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

78 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WWNetworking

Swift-5.8 iOS-16.0 TAG Swift Package Manager-SUCCESS LICENSE

Example.mp4
dependencies: [
    .package(url: "https://github.com/William-Weng/WWNetworking.git", .upToNextMajor(from: "2.1.4"))
]
函式 功能
builder() 建立一個新的WWNetworking
sslPinningSetting(_:delegate:) SSL-Pinning設定 => host + .cer
request(httpMethod:urlString:timeout:contentType:paramaters:headers:cachePolicy:httpBodyType:delegateQueue:result:) 發出URLRequest
header(urlString:timeout:headers:cachePolicy:delegateQueue:result:) 取得該URL資源的HEAD資訊
upload(httpMethod:urlString:timeout:formData:parameters:headers:cachePolicy:delegateQueue:result) 上傳檔案 - 模仿Form
multipleUpload(httpMethod:urlString:timeout:formDatas:parameters:headers:cachePolicy:delegateQueue:result) 上傳檔案 (多個) - 模仿Form
binaryUpload(httpMethod:urlString:timeout:formData:headers:cachePolicy:delegateQueue:progress:completion:) 二進制檔案上傳 - 大型檔案
download(httpMethod:urlString:timeout:configuration:headers:cachePolicy:delegateQueue:progress:completion:) 下載資料 - URLSessionDownloadDelegate
fragmentDownload(httpMethod:urlString:timeout:fragment:configiguration:headers:cachePolicy:delegateQueue:progress:fragmentTask:completion:) 分段下載
multipleDownload(httpMethod:urlStrings:timeout:configuration:headers:cachePolicy:delegateQueue:progress:completion:) 下載多筆資料- URLSessionDownloadDelegate
函式 功能
request(httpMethod:urlString:timeout:contentType:paramaters:headers:cachePolicy:httpBodyType:delegateQueue:) 發出URLRequest
header(urlString:timeout:headers:cachePolicy:delegateQueue:) 取得該URL資源的HEAD資訊
upload(httpMethod:timeout:urlString:formData:parameters:headers:cachePolicy:delegateQueue:) 上傳檔案 - 模仿Form
multipleUpload(httpMethod:urlString:timeout:formDatas:parameters:headers:cachePolicy:delegateQueue:) 上傳檔案 (多個) - 模仿Form
binaryUpload(httpMethod:urlString:timeout:formData:headers:cachePolicy:delegateQueue:) 二進制檔案上傳 - 大型檔案
download(httpMethod:urlString:timeout:configuration:headers:cachePolicy:delegateQueue:) 下載資料 - URLSessionDownloadDelegate
fragmentDownload(httpMethod:urlString:fragment:timeout:configiguration:headers:cachePolicy:delegateQueue:) 分段下載
multipleDownload(httpMethod:urlStrings:timeout:configuration:headers:cachePolicy:delegateQueue:) 下載多筆資料- URLSessionDownloadDelegate
multipleRequest(types:cachePolicy:) 順序執行多個Request
multipleRequestWithTaskGroup(types:cachePolicy:) 同時執行多個Request
multipleRequestWithStream(types:cachePolicy:) 串流執行多個Request
函式 功能
authChalleng(_:host:disposition:credential:) SSL-Pinning的結果

取得公鑰

openssl s_client -connect <your.server.com>:443 -showcerts </dev/null | openssl x509 -outform DER > <server>.cer
openssl s_client -connect google.com:443 -showcerts </dev/null | openssl x509 -outform DER > google.cer
import UIKit
import WWNetworking

final class ViewController: UIViewController {

    @IBOutlet weak var resultTextField: UITextView!
    @IBOutlet var resultImageViews: [UIImageView]!
    @IBOutlet var resultProgressLabels: [UILabel]!
    @IBAction func httpGetAction(_ sender: UIButton) { httpGetTest() }
    @IBAction func httpPostAction(_ sender: UIButton) { httpPostTest() }
    @IBAction func httpDownloadAction(_ sender: UIButton) { httpDownloadData()}
    @IBAction func httpFragmentDownloadAction(_ sender: UIButton) { fragmentDownloadData() }
    @IBAction func httpMultipleDownloadAction(_ sender: UIButton) { httpMultipleDownload() }
    @IBAction func httpUploadAction(_ sender: UIButton) { httpUploadData() }
    @IBAction func httpBinaryUpload(_ sender: UIButton) { httpBinaryUploadData() }
}

// MARK: - ViewController (private class function)
private extension ViewController {

    func httpGetTest() {
        
        let urlString = "https://httpbin.org/get"
        let parameters: [String: String?] = ["name": "William.Weng", "github": "https://william-weng.github.io/"]
        
        Task {
            do {
                let info = try await WWNetworking.shared.request(httpMethod: .GET, urlString: urlString, paramaters: parameters).get()
                displayText(info.data?._jsonSerialization())
            } catch {
                displayText(error)
            }
        }
    }
    
    func httpPostTest() {
        
        let urlString = "https://httpbin.org/post"
        let parameters: [String: Any] = ["name": "William.Weng", "github": "https://william-weng.github.io/"]
        
        Task {
            await WWNetworking.shared.request(httpMethod: .POST, urlString: urlString, paramaters: nil, httpBodyType: .dictionary(parameters)) { result in
                switch result {
                case .failure(let error): self.displayText(error)
                case .success(let info): self.displayText(info.data?._jsonSerialization())
                }
            }
        }
    }
    
    func httpDownloadData() {
        
        let urlString = "https://raw.githubusercontent.com/William-Weng/AdobeIllustrator/master/William-Weng.png"
        let index = 0
        
        displayText("")
        
        Task {
            await WWNetworking.shared.download(urlString: urlString, progress: { info in
                self.displayProgressWithIndex(index, progress: Float(info.totalWritten) / Float(info.totalSize))
            }, completion: { result in
                switch result {
                case .failure(let error): self.displayText(error)
                case .success(let info): self.displayImageWithIndex(index, data: info.data)
                }
            })
        }
    }
    
    func fragmentDownloadData() {
        
        let urlString = "https://photosku.com/images_file/images/i000_803.jpg"
        let index = 1
        
        displayText("")
        
        Task {
            do {
                for try await state in await WWNetworking.shared.fragmentDownload(urlString: urlString) {
                    switch state {
                    case .start(let task): print("task = \(task)")
                    case .finished(let data): displayImageWithIndex(index, data: data)
                    case .progress(let info): displayProgressWithIndex(index, progress: Float(info.totalWritten) / Float(info.totalSize))
                    }
                }
            } catch {
                displayText(error)
            }
        }
    }
    
    func httpMultipleDownload() {
        
        let imageUrlInfos: [String] = [
            ("https://images-assets.nasa.gov/image/PIA18033/PIA18033~orig.jpg"),
            ("https://images-assets.nasa.gov/image/KSC-20210907-PH-KLS01_0009/KSC-20210907-PH-KLS01_0009~orig.jpg"),
            ("https://images-assets.nasa.gov/image/iss065e095794/iss065e095794~orig.jpg"),
        ]

        resultImageViews.forEach { $0.image = nil }
        
        Task {
            await WWNetworking.shared.multipleDownload(urlStrings: imageUrlInfos) { info in
                guard let index = self.displayImageIndex(urlStrings: imageUrlInfos, urlString: info.urlString) else { return }
                self.displayProgressWithIndex(index, progress: Float(info.totalWritten) / Float(info.totalSize))
            } completion: { result in
                switch result {
                case .failure(let error): self.displayText(error)
                case .success(let info):
                    guard let index = self.displayImageIndex(urlStrings: imageUrlInfos, urlString: info.urlString) else { return }
                    self.displayImageWithIndex(index, data: info.data)
                }
            }
        }
    }
    
    func httpUploadData() {
        
        let urlString = "http://192.168.4.200:8080/upload"
        let imageData = resultImageViews[0].image?.pngData()
        let formData: WWNetworking.FormDataInformation = (name: "file", filename: "Demo.png", contentType: .png, data: imageData!)
        
        Task {
            await WWNetworking.shared.upload(urlString: urlString, formData: formData) { result in
                switch result {
                case .failure(let error): self.displayText(error)
                case .success(let info): self.displayText(info.response?.statusCode ?? 404)
                }
            }
        }
    }
    
    func httpBinaryUploadData() {
        
        let urlString = "http://192.168.4.200:8081/binaryUpload"
        let index = 1
        let imageData = resultImageViews[index].image?.pngData()
        let formData: WWNetworking.FormDataInformation = (name: "x-filename", filename: "Large.png", contentType: .octetStream, data: imageData!)
        
        Task {
            await WWNetworking.shared.binaryUpload(urlString: urlString, formData: formData, progress: { info in
                self.title = "\(Float(info.totalBytesSent) / Float(info.totalBytesExpectedToSend))"
            }, completion: { result in
                switch result {
                case .failure(let error): self.displayText(error)
                case .success(let isSuccess): self.displayText(isSuccess)
                }
            })
        }
    }
}

private extension ViewController {
    
    func displayProgressWithIndex(_ index: Int, progress: Float) {
        resultProgressLabels[index].text = "\(progress * 100.0) %"
    }

    func displayImageWithIndex(_ index: Int, data: Data?) {
        guard let data = data else { return }
        resultImageViews[index].image = UIImage(data: data)
    }
    
    func displayText(_ text: Any?) {
        self.resultTextField.text = "\(text ?? "NULL")"
    }
    
    func displayImageIndex(urlStrings: [String], urlString: String?) -> Int? {
        
        guard let urlString = urlString,
              let index = urlStrings.firstIndex(of: urlString)
        else {
            return nil
        }

        return index
    }
}

About

This is a simple integration of HTTP transmission, upload and download functions. It is a rare and good tool for iOS engineers.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors