我想在swift中使用writeToURL将字符串写入本地文件

时间:2016-06-06 04:35:43

标签: swift file local

我的卡片阵列正面和背面都有文字。现在我想将这些数据存储在csv文件中,我创建并添加到我的项目中。以下代码创建由逗号分隔的字符串数组,然后尝试将其写入文件。但文件仍然是空的。代码中没有显示错误。知道我在这里做错了吗?

let path = NSBundle.mainBundle().pathForResource("cardsFile", ofType:"csv")
    for i in 0...cards.count - 1{
        let card = [cards[i].front,cards[i].back]
        let cardRow:String = card.joinWithSeparator(",")
        print(cardRow)///confirmed - carRow is not empty
        do {
            try cardRow.writeToURL(NSURL(fileURLWithPath: path!), atomically: false, encoding: NSUTF8StringEncoding)
        }
        catch {}
    }

1 个答案:

答案 0 :(得分:3)

没有错误显示,因为您正在捕捉错误而没有做任何事情。在print(error)块中添加catch

do {
    try cardRow.writeToURL(NSURL(fileURLWithPath: path!), atomically: false, encoding: NSUTF8StringEncoding)
}
catch {
    print(error)
}

问题是您正在尝试写入捆绑包中的文件,但捆绑包是只读的。您应该尝试写入Documents文件夹:

let fileURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
    .URLByAppendingPathComponent("cardsFile.csv")

顺便说一句,writeToFile将替换输出文件。如果要将数据写入文件,随意附加数据,则可能需要使用NSOutputStream

let fileURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false).URLByAppendingPathComponent("cardsFile.csv")

guard let stream = NSOutputStream(URL: fileURL, append: false) else {
    print("unable to open file")
    return
}

stream.open()

for card in cards {
    let data = "\(card.front),\(card.back)\n".dataUsingEncoding(NSUTF8StringEncoding)!
    guard stream.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length) > 0 else {
        print("unable to write to file")
        break
    }
}

stream.close()

如果目标只是在本地保存,我就不会使用CSV格式。我使用原生格式,例如NSKeyedArchiver。因此,首先通过实施CardNSCoding使init?(coder:)符合encodeWithCoder()协议:

class Card: NSObject, NSCoding {
    let front: String
    let back: String

    init(front: String, back: String) {
        self.front = front
        self.back = back
        super.init()
    }

    required convenience init?(coder aDecoder: NSCoder) {
        guard let front = aDecoder.decodeObjectForKey("front") as? String else { return nil }
        guard let back = aDecoder.decodeObjectForKey("back") as? String else { return nil }
        self.init(front: front, back: back)
    }

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(front, forKey: "front")
        aCoder.encodeObject(back, forKey: "back")
    }

    override var description: String { get { return "<Card front=\(front); back=\(back)>" } }
}

然后,当你想保存时:

let fileURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
    .URLByAppendingPathComponent("cardsFile.bplist")

if !NSKeyedArchiver.archiveRootObject(cards, toFile: fileURL.path!) {
    print("error saving archive")
}

当你想从文件中读取它时:

guard let cards2 = NSKeyedUnarchiver.unarchiveObjectWithFile(fileURL.path!) as? [Card] else {
    print("problem reading archive")
    return
}

print(cards2)