英文:
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()
}
}
}
}
}
}
}
请注意,inputText
在ResultView
结构中作为@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<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()
}
}
}
}
}
}
}
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<AnyCancellable>()
func getPosts(inputText: String) { // <--- 这里
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("输入", text: $inputText)
.onSubmit { // <--- 这里
vm.getPosts(inputText: inputText) // <--- 这里
}
Button("显示结果") {
showResult.toggle()
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
if showResult {
List (vm.posts) { post in // <--- 这里
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<AnyCancellable>()
func getPosts(inputText: String) { // <--- here
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)
.onSubmit { // <--- here
vm.getPosts(inputText: inputText) // <--- here
}
Button("Show Result") {
showResult.toggle()
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
if showResult {
List (vm.posts) { post in // <--- here
Text(post.url)
.font(.headline)
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
}
}
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论