问题描述
我在尝试获取此数据时遇到问题。听说有窍门。任何人都可以创建一个简单的调用来查看来自这个 api 的数据吗?真的会很感激。试了一个星期。我一辈子都无法让这个简单的 api 调用起作用。
http://api.citybik.es/v2/networks
Model.swift
library(shiny)
library(shinyWidgets)
library(shinyjs)
jsCode <- 'shinyjs.winprint = function(){
window.print();
}'
ui <- fluidPage(
fluidPage(title = "Repro"),tags$head(
tags$style(
HTML(".shiny-notification {
position:fixed;
top: calc(50% - 150px);
left: calc(50% - 150px);
}
"
)
)
),useShinyjs(),extendShinyjs(text = jsCode,functions = c("winprint")),sidebarLayout(
sidebarPanel(
textInput("name","Name"),numericInput("Y1","Y1",value = 0,min =0,max = 200),actionButton("print","PRINT")
),mainPanel(
tabsetPanel(type = "tabs",tabPanel("Random Var1",tableOutput("x1"))
)
)
)
)
server <- function(input,output,session) {
Var1 <- c(1,2,3,4,5,6,7,8,9,10)
X1 <- c(0.01,0.1,0.04,0.01,100,0.5)
Units <- c("a","a","b","c","c")
table <- data.frame(Var1,X1,Units)
Y1 <- reactive({
get(input$Y1,inherits = FALSE)
})
output$x1 <- renderTable({
transform(table,X2 = input$Y1 * case_when(Var1 %in% c(1,8) ~ 0.01,Var1 == 2 ~ 1,Var1 %in% c(3,6) ~ 0.04,Var1 == 4 ~ 50,Var1 == 5 ~ 2,Var1 == 9 ~ 4,Var1 == 10 ~ 0.5))
})
observeEvent(input$print,{
js$winprint()
})
}
# App
shinyApp(ui,server)
Contentview.swift
import Foundation
// MARK: - Welcome
struct Dataset: Codable {
let networks: [Network]
}
// MARK: - Network
struct Network: Codable {
let company: [String]
let href,id: String
let location: Location
let name: String
}
// MARK: - Location
struct Location: Codable {
let city,country: String
let latitude,longitude: Double
}
解决方法
从“https://api.citybik.es/v2/networks”复制整个json 进入“https://app.quicktype.io/”并从中获取(正确的)swift数据结构。 将“欢迎”重命名为“响应”并在您的代码中使用它。
使用:“https://api.citybik.es/v2/networks”注意https。
编辑:在您的代码中:
struct ContentView: View {
@State var networks = [Network]()
var body: some View {
List(networks,id: \.id) { network in
VStack {
Text(network.name)
Text(network.location.city)
}
}.onAppear(perform: loadData)
}
func loadData() {
guard let url = URL(string: "https://api.citybik.es/v2/networks") else {
print("Your API end point is Invalid")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data,response,error in
if let data = data {
if let response = try? JSONDecoder().decode(Response.self,from: data) {
DispatchQueue.main.async {
self.networks = response.networks
}
return
}
}
}.resume()
}
}
一旦你有了所有的数据结构, 如果你在 ios 15 或 macos 12 上使用 Swift 5.5,你可以使用这样的东西:
struct ContentView: View {
@State var networks = [Network]()
var body: some View {
List(networks,id: \.id) { network in
VStack {
Text(network.name)
Text(network.location.city)
}
}
.task {
let response: Response? = await fetchNetworks()
if let resp = response {
networks = resp.networks
}
}
}
func fetchNetworks<T: Decodable>() async -> T? {
let url = URL(string: "https://api.citybik.es/v2/networks")!
let request = URLRequest(url: url)
do {
let (data,response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,httpResponse.statusCode == 200 else {
// throw URLError(.badServerResponse) // todo
print(URLError(.badServerResponse))
return nil
}
let results = try JSONDecoder().decode(T.self,from: data)
return results
}
catch {
return nil
}
}
}