当用户将一个十六进制代码粘贴到我的textfield中时,我希望我的API函数接受这个十六进制代码,并在API调用中使用它作为参数。这意味着我必须从我的视图(包含textfield)到我的类(包含API调用)共享数据。做这件事最好的方法是什么?感谢你的时间和建议
视图:
import SwiftUI
struct TestingText: View {
@StateObject var fetch = fetchResults()
@Binding var text: String
var body: some View {
VStack {
TextField("Paste Clout Hexcode Here", text: $text)
.font(.title2)
.padding()
Text(fetch.clout.postFound?.body ?? "n/a")
}
}
}
struct TestingText_Previews: PreviewProvider {
static var previews: some View {
TestingText(text: .constant("8004bb672ad3f46118775cd4b2cb5306c63f6d68787457990bf0d2fda3f7993a"))
}
}具有API调用的类:
class fetchResults: ObservableObject {
@Published var clout = Cloutington()
@Published var dataHasLoaded = false
@State var postHashHex: String = "8004bb672ad3f46118775cd4b2cb5306c63f6d68787457990bf0d2fda3f7993a"
init() {
getData { clout in
self.clout = clout
}
}
private func getData(completion: @escaping (Cloutington) -> ()) {
let parameters = "{\r\n \"PostHashHex\": \"\(postHashHex)\"\r\n}"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string: "https://bitclout.com/api/v0/get-single-post")!,timeoutInterval: Double.infinity)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = postData
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request) { (responseData, response, error) in
print(error)
print(response)
print(responseData)
if let resData = responseData {
let decoder = JSONDecoder()
do
{
let finalData = try decoder.decode(Cloutington.self, from: resData)
DispatchQueue.main.async {
completion(finalData)
self.dataHasLoaded = true
}
}
catch (let error)
{
print(error)
}
}
}
task.resume()
}
}带有JSON数据的模型:
import Foundation
struct Cloutington: Decodable {
var postFound: PostFound?
enum CodingKeys: String, CodingKey {
case postFound = "PostFound"
}
}
struct PostFound: Decodable {
var id: String?
var postHashHex, posterPublicKeyBase58Check, parentStakeID, body: String?
var imageURLs: [String]?
// var recloutedPostEntryResponse: JSONNull?
var creatorBasisPoints, stakeMultipleBasisPoints: Int?
var timestampNanos: Double?
var isHidden: Bool?
var confirmationBlockHeight: Int?
var inMempool: Bool?
var profileEntryResponse: ProfileEntryResponse?
var likeCount, diamondCount: Int?
var isPinned: Bool?
var commentCount, recloutCount: Int?
var diamondsFromSender: Int?
enum CodingKeys: String, CodingKey {
case postHashHex = "PostHashHex"
case posterPublicKeyBase58Check = "PosterPublicKeyBase58Check"
case parentStakeID = "ParentStakeID"
case body = "Body"
case imageURLs = "ImageURLs"
case creatorBasisPoints = "CreatorBasisPoints"
case stakeMultipleBasisPoints = "StakeMultipleBasisPoints"
case timestampNanos = "TimestampNanos"
case isHidden = "IsHidden"
case confirmationBlockHeight = "ConfirmationBlockHeight"
case inMempool = "InMempool"
case profileEntryResponse = "ProfileEntryResponse"
case likeCount = "LikeCount"
case diamondCount = "DiamondCount"
case isPinned = "IsPinned"
case commentCount = "CommentCount"
case recloutCount = "RecloutCount"
case diamondsFromSender = "DiamondsFromSender"
}
}
// MARK: - ProfileEntryResponse
struct ProfileEntryResponse: Decodable {
var publicKeyBase58Check, username, profileEntryResponseDescription, profilePic: String?
var isHidden, isReserved, isVerified: Bool?
var coinPriceBitCloutNanos, stakeMultipleBasisPoints: Int?
enum CodingKeys: String, CodingKey {
case publicKeyBase58Check = "PublicKeyBase58Check"
case username = "Username"
case profileEntryResponseDescription = "Description"
case profilePic = "ProfilePic"
case isHidden = "IsHidden"
case isReserved = "IsReserved"
case isVerified = "IsVerified"
case coinPriceBitCloutNanos = "CoinPriceBitCloutNanos"
case stakeMultipleBasisPoints = "StakeMultipleBasisPoints"
}
}发布于 2021-09-23 12:37:32
首先,不要像fetchResults那样用小写命名类,也不要像调用动作那样调用类:每个程序员都希望fetchResults()是一个函数调用。使用类似于ResultFetcher的东西来命名这个类。类实例通常是小写的类名,或者它的一部分:
@StateObject var resultFetcher = ResultFetcher()
// or
@StateObject var fetcher = ResultFetcher()您只能在@State视图中使用SwiftUI,不能在ObservableObject中使用它。如果您需要在更新该变量后更新视图,或者使用未注释的变量,请使用@Published。
在您的示例中,它看起来不需要存储这个哈希字符串;您可以直接从视图中传递它。
可以使用.onChange(of: text)跟踪对@State或@Binding变量的更改:
TextField("Paste Clout Hexcode Here", text: $text)
.font(.title2)
.padding()
.onChange(of: text) { text in
resultFetcher.updateData(postHashHex: text)
}不确定是否需要使用硬编码十六进制代码对updateData的初始调用,无论如何,您的视图模型可以更新为:
class ResultFetcher: ObservableObject {
@Published var clout = Cloutington()
@Published var dataHasLoaded = false
private let initialPostHashHex: String = "8004bb672ad3f46118775cd4b2cb5306c63f6d68787457990bf0d2fda3f7993a"
init() {
updateData(postHashHex: initialPostHashHex)
}
func updateData(postHashHex: String) {
getData(postHashHex: postHashHex) { clout in
self.clout = clout
}
}
private func getData(postHashHex: String, completion: @escaping (Cloutington) -> ()) {
// your code
}
}https://stackoverflow.com/questions/69299151
复制相似问题