URLSession API 请求被发出两次而不是一次

问题描述

我有一个包,旨在让 Unsplash API 和 SwiftUI 的使用变得简单。这是 The GitHub link 。我遇到了一个问题,当我使用以下代码测试包时,API 被请求两次而不是一次。这使得链接到 Unsplash 上的图像的文本(api 的要求)对于正在显示的图像不正确。

import SwiftUI
import UnsplashSwiftUI

var accessKey = "xxx"

struct UnsplashRandomTest: View {
    var body: some View {
        ZStack {
            LinearGradient (gradient: Gradient(colors: [Color.blue,Color.black]),startPoint: .topLeading,endPoint: .bottomTrailing).ignoresSafeArea()
            UnsplashRandom(clientId: accessKey,orientation: .portrait,aspectRatio: .fill)
                .clipShape(RoundedRectangle(cornerRadius: 15))
                .shadow(radius: 25)
                .frame(width: 350,height: 350)
                .padding(10)
        }
    }
}

struct UnsplashRandomTest_Previews: PreviewProvider {
    static var previews: some View {
        UnsplashRandomtest()
    }
}

这是被调用的主视图:

import SwiftUI
public struct UnsplashRandom: View {
    
    //MARK: Parameters
    //required parameters
    var clientId: String //Unsplash API access key
    
    public enum Orientations: String{
        case landscape = "landscape"
        case portrait = "portrait"
        case squarish = "squarish"
        case none = ""
    }
    
    //Optional parameters
    var query: String // Limit selection to photos matching a search term.
    var orientation: Orientations // Filter by photo orientation. (Valid values:  landscape,portrait,squarish)
    var textColor: Color // Color of the text hotlinked to image on Unsplash
    var textBackgroundColor: Color // Color of text background (opacity set to 0.2 automatically)
    var aspectRatio: ContentMode // aspect ratio's content mode (.fit or .fill)
    
    //Unsplash API data
    @Observedobject var api : UnsplashAPI
    
    //MARK: Init
    public init(clientId: String,query: String = "",orientation: Orientations = .none,textColor: Color = .white,textBackgroundColor: Color = .black,aspectRatio: ContentMode = .fit){
        self.clientId = clientId
        self.query = query
        self.orientation = orientation

        
        self.textColor = textColor
        self.textBackgroundColor = textBackgroundColor
        self.aspectRatio = aspectRatio
        
        let url = URL(string: "https://api.unsplash.com/")!
        
        guard var components = URLComponents(url: url.appendingPathComponent("photos/random"),resolvingAgainstBaseURL: true)
        else { fatalError("Couldn't append path component")}

        components.queryItems = [URLQueryItem(name: "client_id",value: clientId)]
        if query != "" {components.queryItems?.append(URLQueryItem(name: "query",value: query))}
        if orientation != .none {components.queryItems?.append(URLQueryItem(name: "orientation",value: orientation.rawValue))}
        
        self.api = UnsplashAPI(components: components)
    }
    
    //MARK: Body
    public var body: some View {
        Group {
            //Detecting API status
            switch self.api.state {
            case .loading:
                //Placeholder
                ProgressView()
                    .progressViewStyle(CircularProgressViewStyle())
            case .loaded(let unsplashData):
                //MARK: Main View
                ZStack(alignment: .bottomTrailing) {
                    //MARK: Remote Image
                    AsyncImage(
                        url: URL(string: unsplashData.urls!.raw!)!,//Remote image URL
                        placeholder: { //Placerholder while image loads
                            vstack {
                                Spacer()
                                HStack {
                                    Spacer()
                                    ProgressView()
                                        .progressViewStyle(CircularProgressViewStyle())
                                    Spacer()
                                }
                                Spacer()
                            } //Placeholder ends
                        },image: { Image(uiImage: $0).resizable() }
                    )
                    .aspectRatio(contentMode: aspectRatio)
                    //MARK: Text(Hotlink)
                    HStack(spacing: 0){
                        Text("Photo by ")
                            .font(.subheadline)
                            .foregroundColor(textColor)
                        
                        //Link to original image on Unsplash
                        Link(destination: URL(string: unsplashData.links!.html!)!,label: {
                            Text(unsplashData.user!.name!)
                                .font(.subheadline)
                                .underline()
                                .bold()
                                .foregroundColor(textColor)
                        })
                        
                        Text(" on ")
                            .font(.subheadline)
                            .foregroundColor(textColor)
                        
                        //Link to Unsplash
                        Link(destination: URL(string: "https://unsplash.com")!,label: {
                            Text("Unsplash")
                                .font(.subheadline)
                                .underline()
                                .bold()
                                .foregroundColor(textColor)
                        })
                    }
                    .padding(5)
                    .background(RoundedRectangle(cornerRadius: 7.5).foregroundColor(textBackgroundColor).opacity(0.2))
                    .padding(5)
                }
            }
        }
        .onAppear {
            self.api.request() //Request to the API
            print("request made")
        }
    }
}

代码取自开发分支上的 UnsplashSwiftUI.swift。当我运行上面的测试时,“request made”会打印两次。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)