如何在函数中从文本字段传递数据到URL。

huangapple go评论55阅读模式
英文:

How to pass data from textfield to url in function

问题

在您提供的代码中,您似乎想要访问名为inputText的属性,但它在您的DownloadWithCombineViewModel类中找不到定义。您可能需要将inputText传递给getPosts方法,或者在合适的位置定义它。

以下是您提供的代码的翻译,我将保留代码不变,只提供翻译部分,不包含其他内容:

import Combine
import SwiftUI

struct PostModel: Identifiable, Codable {
    let id: String
    let url: String
}

class DownloadWithCombineViewModel: ObservableObject {

    @Published var posts: [PostModel] = []
    var cancellables = Set<AnyCancellable>()

    init() {
        getPosts()
    }

    func getPosts() {
        guard let url = URL(string: "https://example\(inputText)")
        else { return }
        URLSession.shared.dataTaskPublisher(for: url)
        
            .receive(on: DispatchQueue.main)
            .tryMap(handleOutput)
            .decode(type: PostModel.self, decoder: JSONDecoder())
            .replaceError(with: PostModel(id: "", url: ""))
            .sink(receiveValue: { [weak self] returnedPosts in
                self?.posts = [returnedPosts]
            })
            .store(in: &cancellables)
    }
    
    func handleOutput(output: URLSession.DataTaskPublisher.Output) throws -> Data {
        guard
            let response = output.response as? HTTPURLResponse,
            response.statusCode >= 200 && response.statusCode < 300 else {
            throw URLError(.badServerResponse)
        }
        return output.data
    }
}

struct ResultView: View {

    @State var inputText = ""
    @State var showResult = false
    @StateObject var vm = DownloadWithCombineViewModel()

    var body: some View {
        NavigationView {
            VStack {
                TextField("Enter", text: $inputText)
                
                Button("Show Result") {
                    showResult.toggle()
                }
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(10)
                
                if showResult {
                    List {
                        ForEach(vm.posts) { post in
                            VStack(alignment: .leading) {
                                Text(post.url)
                                    .font(.headline)
                            }
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding()
                        }
                    }
                }
            }
        }
    }
}

请注意,inputTextResultView结构中作为@State属性进行了定义。如果您在DownloadWithCombineViewModel类中需要访问它,您可以将它传递给getPosts方法。

英文:
import Combine
import SwiftUI

struct PostModel: Identifiable, Codable {
    let id: String
    let url: String
}

class DownloadWithCombineViewModel: ObservableObject {
    
    @Published var posts: [PostModel] = []
    var cancellables = Set&lt;AnyCancellable&gt;()
    
    init() {
        getPosts()
    }
    
    func getPosts() {
        guard let url = URL(string: &quot;https://example\(inputText)&quot;)
        else { return }
        URLSession.shared.dataTaskPublisher(for: url)
        
            .receive(on: DispatchQueue.main)
            .tryMap(handleOutput)
            .decode(type: PostModel.self, decoder: JSONDecoder())
            .replaceError(with: PostModel(id: &quot;&quot;, url: &quot;&quot;))
            .sink(receiveValue: { [weak self] returnedPosts in
                self?.posts = [returnedPosts]
            })
            .store(in: &amp;cancellables)
    }
    
    func handleOutput(output: URLSession.DataTaskPublisher.Output) throws -&gt; Data {
        guard
            let response = output.response as? HTTPURLResponse,
            response.statusCode &gt;= 200 &amp;&amp; response.statusCode &lt; 300 else {
            throw URLError(.badServerResponse)
        }
        return output.data
    }
}
struct ResultView: View {
    
    @State var inputText = &quot;&quot;
    @State var showResult = false
    @StateObject var vm = DownloadWithCombineViewModel()
    
    var body: some View {
        NavigationView {
            VStack {
                TextField(&quot;Enter&quot;, text: $inputText)
                
                Button(&quot;Show Result&quot;) {
                    
                    showResult.toggle()
                }
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(10)
                
                if showResult {
                   
                    List {
                        ForEach(vm.posts) { post in
                            VStack(alignment: .leading) {
                                Text(post.url)
                                    .font(.headline)
                            }
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding()
                        }
                    }
                }
            }
        }
    }
}

Tried different options, but still does not see inputText. It is possible to do this??

答案1

得分: 1

尝试这种简单的方法,其中有一个名为 func getPosts(inputText: String) 的函数,并在 TextField 上使用 .onSubmit {...}(即按回车键)来触发 getPosts 函数。

struct PostModel: Identifiable, Codable {
    let id: String
    let url: String
}

class DownloadWithCombineViewModel: ObservableObject {
    
    @Published var posts: [PostModel] = []
    var cancellables = Set&lt;AnyCancellable&gt;()
    
    func getPosts(inputText: String) {  // &lt;--- 这里
        guard let url = URL(string: &quot;https://example\(inputText)&quot;)
        else { return }
        URLSession.shared.dataTaskPublisher(for: url)
            .receive(on: DispatchQueue.main)
            .tryMap(handleOutput)
            .decode(type: PostModel.self, decoder: JSONDecoder())
            .replaceError(with: PostModel(id: &quot;&quot;, url: &quot;&quot;))
            .sink(receiveValue: { [weak self] returnedPosts in
                self?.posts = [returnedPosts]
            })
            .store(in: &amp;cancellables)
    }
    
    func handleOutput(output: URLSession.DataTaskPublisher.Output) throws -&gt; Data {
        guard
            let response = output.response as? HTTPURLResponse,
            response.statusCode &gt;= 200 &amp;&amp; response.statusCode &lt; 300 else {
            throw URLError(.badServerResponse)
        }
        return output.data
    }
}

struct ResultView: View {
    @State var inputText = &quot;&quot;
    @State var showResult = false
    @StateObject var vm = DownloadWithCombineViewModel()
    
    var body: some View {
        NavigationView {
            VStack {
                TextField(&quot;输入&quot;, text: $inputText)
                    .onSubmit {  // &lt;--- 这里
                        vm.getPosts(inputText: inputText)  // &lt;--- 这里
                    }
                Button(&quot;显示结果&quot;) {
                    showResult.toggle()
                }
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(10)
                
                if showResult {
                    List (vm.posts) { post in  // &lt;--- 这里
                        Text(post.url)
                            .font(.headline)
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding()
                    }
                }
            }
        }
    }
}

这是你提供的代码的中文翻译。

英文:

Try this simple approach where you have func getPosts(inputText: String) and use
.onSubmit {...} (that is press return) on the TextField to action the getPosts function.

struct PostModel: Identifiable, Codable {
    let id: String
    let url: String
}

class DownloadWithCombineViewModel: ObservableObject {
    
    @Published var posts: [PostModel] = []
    var cancellables = Set&lt;AnyCancellable&gt;()
    
    func getPosts(inputText: String) {  // &lt;--- here
        guard let url = URL(string: &quot;https://example\(inputText)&quot;)
        else { return }
        URLSession.shared.dataTaskPublisher(for: url)
            .receive(on: DispatchQueue.main)
            .tryMap(handleOutput)
            .decode(type: PostModel.self, decoder: JSONDecoder())
            .replaceError(with: PostModel(id: &quot;&quot;, url: &quot;&quot;))
            .sink(receiveValue: { [weak self] returnedPosts in
                self?.posts = [returnedPosts]
            })
            .store(in: &amp;cancellables)
    }
    
    func handleOutput(output: URLSession.DataTaskPublisher.Output) throws -&gt; Data {
        guard
            let response = output.response as? HTTPURLResponse,
            response.statusCode &gt;= 200 &amp;&amp; response.statusCode &lt; 300 else {
            throw URLError(.badServerResponse)
        }
        return output.data
    }
}

struct ResultView: View {
    @State var inputText = &quot;&quot;
    @State var showResult = false
    @StateObject var vm = DownloadWithCombineViewModel()
    
    var body: some View {
        NavigationView {
            VStack {
                TextField(&quot;Enter&quot;, text: $inputText)
                    .onSubmit {  // &lt;--- here
                        vm.getPosts(inputText: inputText)  // &lt;--- here
                    }
                Button(&quot;Show Result&quot;) {
                    showResult.toggle()
                }
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(10)
                
                if showResult {
                    List (vm.posts) { post in  // &lt;--- here
                        Text(post.url)
                            .font(.headline)
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding()
                    }
                }
            }
        }
    }
}

huangapple
  • 本文由 发表于 2023年3月1日 08:39:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75598625.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定