简体   繁体   English

Swift - 从返回数组的 function 创建堆栈(文本视图)

[英]Swift - Creating a stack (Text view) from a function that returns an array

I am trying to create a list of text objects out of a function that returns an array of params.我正在尝试从返回参数数组的 function 创建文本对象列表。 Everything seems to be working fine, getting the data, console shows the correct results, except the list itself which remains empty.一切似乎都工作正常,获取数据,控制台显示正确的结果,除了列表本身仍然是空的。

The function call: function 来电:

import UIKit
import SwiftUI

struct SubdomainsList: View {

    @State var SubDomains = VTData().funky(XDOMAIN: "giphy.com")
    
    var body: some View {
            VStack {
                List{
                    Text("Subdomains")
                    ForEach(SubDomains, id: \.self) { SuDo in
                        Text(SuDo)
                    }
                }
            }
        }
}

struct SubdomainsList_Previews: PreviewProvider {
    static var previews: some View {
        SubdomainsList()
    }
}

The Json handlers: Json 处理程序:

struct VTResponse: Decodable {
    let data: [VT]
}

struct VT: Decodable {
    var id: String
}

The class: class:

class VTData {
    func funky (XDOMAIN: String) -> Array<String>{
        var arr = [""]
        getDATA(XDOMAIN: "\(XDOMAIN)", userCompletionHandler: { (SubDomain) in
            print(SubDomain)
            arr.append(SubDomain)
            return SubDomain
        })
        return arr
    }
    
    
    func getDATA(XDOMAIN: String, userCompletionHandler: @escaping ((String) -> String))  {
        let token = "<TOKEN>"
        guard let url = URL(string: "https://www.lalalla.com/subdomains") else {fatalError("Invalid URL")}
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.setValue("\(token)", forHTTPHeaderField: "x-apikey")
        
        let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
            guard let data = data else { return }
            let decoder = JSONDecoder()
            let result = try? decoder.decode(VTResponse.self, from: data)
            if let result = result {
                for SubDo in result.data {
                    let SubDomain = SubDo.id
                    userCompletionHandler(SubDomain)
                }
            }
            else {
                fatalError("Could not decode")
            }
        })
            task.resume()
    }
    
}

I'm getting no errors whatsoever, and the console output shows the correct results:我没有收到任何错误,控制台 output 显示了正确的结果:

support.giphy.com
cookies.giphy.com
media3.giphy.com
i.giphy.com
api.giphy.com
developers.giphy.com
media.giphy.com
x-qa.giphy.com
media2.giphy.com
media0.giphy.com

It is also worth mentioning that when I add print(type(of: SubDomain)) to the code I'm getting a String rather than an array.还值得一提的是,当我将print(type(of: SubDomain))添加到代码中时,我得到的是一个字符串而不是一个数组。

The preview: preview预览:预览

Any ideas?有任何想法吗?

try this approach, again, to extract the list of subdomain from your API, and display them in a List using the asynchronous function getDATA(...) :再次尝试这种方法,从您的 API 中提取subdomain列表,并使用异步function getDATA(...)将它们显示在List中:

class VTData {
    
    // `func funky` is completely useless, remove it
    
    func getDATA(XDOMAIN: String, completion: @escaping ([String]) -> Void) { // <-- here
        let token = "<TOKEN>"
        guard let url = URL(string: "https://www.virustotal.com/api/v3/domains/\(XDOMAIN)/subdomains") else {
            print("Invalid URL")
            return
        }
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.setValue("\(token)", forHTTPHeaderField: "x-apikey")
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else { return } // todo return some error msg
            do {
                let results = try JSONDecoder().decode(VTResponse.self, from: data)
                return completion(results.data.map{ $0.id }) // <-- here
            } catch {
                print(error) // <-- here important
            }
        }.resume()
    }
    
}

struct SubdomainsList: View {
    @State var subDomains: [String] = []  // <--- here
    
    var body: some View {
        VStack {
            List{
                Text("Subdomains")
                ForEach(subDomains, id: \.self) { SuDo in
                    Text(SuDo)
                }
            }
        }
        .onAppear {
            // async function
            VTData().getDATA(XDOMAIN: "giphy.com") { subs in  // <--- here
                subDomains = subs
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM