首页 > 解决方案 > 如何在swift ui中从字符串中获取子字符串?

问题描述

在 UIKit 中,我使用相同的方法从一个长字符串中只获取一个部分,并且它在那里工作。但是它在 swift ui 应用程序中不起作用。我想知道它是否可能不是一个字符串,而是别的东西。有谁知道一个更好的解决方案,只从长文本中获取一个短子字符串?

let url = URL(string: "https://midcdmz.nrel.gov/apps/spa.pl?syear=2020&smonth=1&sday=1&eyear=2020&emonth=1&eday=1&otype=0&step=60&stepunit=1&hr=12&min=0&sec=0&latitude=39.743&longitude=-105.178&timezone=-7.0&elev=1829&press=835&temp=10&dut1=0.0&deltat=64.797&azmrot=180&slope=0&refract=0.5667&field=0")

struct ContentView: View {
    
    
    var html = try! String(contentsOf: url!, encoding: String.Encoding.ascii)
    
    let leftSideOfTheValue = "1/1/2020,0:00:00,"
    
    let rightSideOfTheValue = "1/1/2020,1:00:00,"
    
    guard let leftRange = html.range(of: leftSideOfTheValue) else {
        print("cant find left range")
        return
    }
    
    guard let rightRange = html.range(of: rightSideOfTheValue) else {
        print("cant find right range")
        return
    
    let rangeOfTheValue = leftRange.upperBound..<rightRange.lowerBound
    
    let elevationInfo = (html[rangeOfTheValue])
    
    var body: some View {
        Text(elevationInfo)
                
    }

标签: arraysswiftstring

解决方案


该问题与 Swift UI 无关,以下解决方案是通用的。

正如我多次所说,接收到的数据是 CSV(逗号分隔值),每一行都是一条记录,字段用逗号分隔。

要解析字符串,首先创建一个自定义结构

struct ZenithData {
    let date : Date
    let angle : Double
}

和一个数据源数组

var zenithData = [ZenithData]()

然后用 异步加载数据URLSession,将文本拆分为行,将行拆分为字段,连接日期和时间部分并将其转换为Date并填充数组。

注意:确切的日期格式不明确。格式也可以d/M/yyyy

let url = URL(string: "https://midcdmz.nrel.gov/apps/spa.pl?syear=2020&smonth=1&sday=1&eyear=2020&emonth=1&eday=1&otype=0&step=60&stepunit=1&hr=12&min=0&sec=0&latitude=39.743&longitude=-105.178&timezone=-7.0&elev=1829&press=835&temp=10&dut1=0.0&deltat=64.797&azmrot=180&slope=0&refract=0.5667&field=0")

let dataTask = URLSession.shared.dataTask(with: url!) { data, _, error in
    if let error = error { print(error); return }
    let string = String(data: data!, encoding: .utf8)!
    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    dateFormatter.dateFormat = "M/d/yyyy H:mm:ss"
    
    let lines = string.components(separatedBy: CharacterSet.newlines)
    for i in 1..<lines.count { // first line is dropped
        let fields = lines[i].components(separatedBy: ",")
        if fields.count != 3 { continue }
        let date = dateFormatter.date(from: fields[0] + " " + fields[1])!
        let angle = Double(fields[2])!
        zenithData.append(ZenithData(date: date, angle: angle))
    }
    print(zenithData)
}
dataTask.resume()

推荐阅读