Swift 获取并解析固定宽度的文本文件

Swift Fetch and Parse Fixed Width Text File

我正在尝试下载具有固定宽度数据元素的文本文件并创建 一组数据(最终我会将其存储在核心数据中)。

这是此文件中的数据示例:

USC00054542 37.2000 -103.4833 1770.9 CO KIM 5 SW
USC00054546 37.1150 -103.2986 1602.3 CO KIM 10SSE
USC00054584 39.2833 -104.4333 1937.0 CO KIOWA 5 SE
USC00054585 39.3000 -104.5167 1998.0 CO KIOWA 4 SW
USC00054592 39.6167 -102.5833 1220.1 CO KIRK
USC00054603 38.7658 -102.8031 1311.2 CO KIT 卡森

我为每行中的对象创建了一个结构:

struct RawStation: Codable, Identifiable {
    var id = UUID()
    var station: String
    var lat: String
    var long: String
    var elevation: String
    var name: String
    var region: String
    var postal: String
}

我尝试了几种解码此文件的方法,但都没有成功。这里是 尝试使用 PropertyListDecoder

class Webservice {
    func fetchTextFile() {
        let stationURL = URL(string: "https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/ghcnd-stations.txt")!
        var s: [RawStation]?

        if let data = try? Data(contentsOf: stationURL) {
          let decoder = PropertyListDecoder()
          s = try? decoder.decode([RawStation].self, from: data)
        }

        do {
            let data = try Data(contentsOf: stationURL)
            let decoder = PropertyListDecoder()
            s = try decoder.decode([RawStation].self, from: data)
        } catch {
            // Handle error
            print(error)
        }
        print(s as Any)
    } 
}

错误信息: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not a valid property list.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Unexpected character A at line 1" UserInfo={NSDebugDescription=Unexpected character A at line 1, kCFPropertyListOldStyleParsingError =Error Domain=NSCocoaErrorDomain Code=3840 "Expected ';' or '=' after key at line 1" UserInfo={NSDebugDescription=Expected ';' or '=' after key at line 1}})))

文件的 url 是“https://www1.ncdc.noaa.gov/pub/data/ghcn/daily/ghcnd-stations.txt

遗憾的是,数据似乎无法作为 JSON 文件使用。

Xcode 11.4.1 任何指导将不胜感激。

Codable 在这里不适合您,因为这不是结构化数据格式。不幸的是,您将不得不下载该文件,然后创建一个解析器来解码文件的每一行,并使用它来创建您的个人数据项。

看看 NSScanner 可能对你有帮助。

我又快速看了一眼,比那更容易。记录格式:

Variable   Columns   Type
------------------------------
ID            1-11   Character
LATITUDE     13-20   Real
LONGITUDE    22-30   Real
ELEVATION    32-37   Real (-999.9 indicates a missing value)
STATE        39-40   Character (US stations only)
NAME         42-71   Character
GSN FLAG     73-75   Character (Optional)
HCN/CRN FLAG 77-79   Character (Optional)
WMO ID       81-85   Character (Optional)
------------------------------

所以您只需要从这些字符串范围中提取数据并使用它来创建您的属性。