i saving csv file , emailing it. works csv not formatted correctly. of items should moved new row included the second column of existing row. there 5 columns, id, name, model, ups, , price. there i've done wrong when creating file?
func openactions() { actions = uialertcontroller(title: "", message: "", preferredstyle: .actionsheet) let cancelaction = uialertaction(title: "cancel", style: .cancel, handler: { (action) -> void in self.actions?.dismissviewcontrolleranimated(true, completion: nil) }) let savecsv = uialertaction(title: "save csv", style: .default, handler: { (action) -> void in self.getandsaveitems() self.actions?.dismissviewcontrolleranimated(true, completion: nil) }) let viewfile = uialertaction(title: "view csv", style: .default, handler: { (action) -> void in self.viewfile() self.actions?.dismissviewcontrolleranimated(true, completion: nil) }) let emailfile = uialertaction(title: "email csv", style: .default, handler: { (action) -> void in self.emailfile() self.actions?.dismissviewcontrolleranimated(true, completion: nil) }) actions?.addaction(cancelaction) actions?.addaction(emailfile) actions?.addaction(viewfile) actions?.addaction(savecsv) self.presentviewcontroller(actions!, animated: true, completion: nil) } func datafilepath() -> string { let paths = nssearchpathfordirectoriesindomains(.documentdirectory, .userdomainmask, true) let documentsdirectory = paths[0] let titlestring = self.title!.stringbyreplacingoccurrencesofstring(" ", withstring: "_") let string = string(format: "/%@.csv", titlestring) return documentsdirectory.stringbyappendingstring(string) } func getandsaveitems() { let getlimit = 1000 var getskip = 0 activityindicator?.startanimating() let query = pfquery(classname: "items") query.wherekey("user", equalto: pfuser.currentuser()!) query.wherekey("collection", equalto: self.title!) query.orderbyascending("item") query.limit = getlimit query.skip = getskip query.findobjectsinbackgroundwithblock( { (objects, error) -> void in if error == nil { if let objects = objects [pfobject]! { object in objects { self.names.append(object["item"] as! string) self.upcs.append(object["upc"] as! string) self.ids.append(object.objectid!) self.models.append(object["model"] as! string) self.prices.append(object["pricepaid"] as! string) if object["notes"] == nil { self.notes.append(nil) } else { self.notes.append(object["notes"] as? string) } } } if objects!.count == getlimit { getskip += getlimit self.getandsaveitems() } } else { // show error... } }) writetofile() } func writetofile() { if (!nsfilemanager.defaultmanager().fileexistsatpath(self.datafilepath())) { nsfilemanager.defaultmanager().createfileatpath(self.datafilepath(), contents: nil, attributes: nil) } // var writestring = nsmutablestring(capacity: 0) var writestring = string() writestring.reservecapacity(0) (var = 0; < names.count; i++) { let stringtowrite = string(format: "%@,%@,%@,%@,%@, \n", ids[i], names[i], models[i], upcs[i], prices[i]) writestring.appendcontentsof(stringtowrite) } let handle = nsfilehandle(forwritingatpath: self.datafilepath()) handle?.truncatefileatoffset((handle?.seektoendoffile())!) handle?.writedata(writestring.datausingencoding(nsutf8stringencoding)!) self.activityindicator?.stopanimating() } func viewfile() { if (nsfilemanager.defaultmanager().fileexistsatpath(datafilepath())) { let filedata = nsdata(contentsoffile: datafilepath()) let filevc = fileviewcontroller(nibname: "fileviewcontroller", bundle: nil) let navcontroller = navcontroller(rootviewcontroller: filevc) filevc.filedata = filedata self.presentviewcontroller(navcontroller, animated: true, completion: nil) } else { // file doesn't exist... print("file doesn't exist") } } func emailfile() { if (nsfilemanager.defaultmanager().fileexistsatpath(datafilepath())) { if mfmailcomposeviewcontroller.cansendmail() { let mailcomposer = mfmailcomposeviewcontroller() mailcomposer.mailcomposedelegate = self let subject = string(format: "my %@ collection", self.title!) mailcomposer.setsubject(subject) mailcomposer.setmessagebody("", ishtml: false) let filedata = nsdata(contentsoffile: datafilepath()) let titlestring = self.title!.stringbyreplacingoccurrencesofstring(" ", withstring: "_") let filenamestring = string(format: "%@.csv", titlestring) mailcomposer.addattachmentdata(filedata!, mimetype: "text/csv", filename: filenamestring) self.presentviewcontroller(mailcomposer, animated: true, completion: nil) } else { // can't send mail... } } else { // file doesn't exist... print("file doesn't exist") } } func mailcomposecontroller(controller: mfmailcomposeviewcontroller, didfinishwithresult result: mfmailcomposeresult, error: nserror?) { self.dismissviewcontrolleranimated(true, completion: nil) }
this line:
let stringtowrite = string(format: "%@,%@,%@,%@,%@, \n", ids[i], names[i], models[i], upcs[i], prices[i])
is using create each line of csv file. work in simple cases.
here csv rules:
- if field value contains field separator (comma in case), quote, whitespace @ either end of value, or newlines, field value must enclosed in quotes (usually double-quotes).
- if field value contains quote characters, must escape each quote character quote character.
creating , parsing csv files more involved people realize.
either modify logic add needed quoting or find 3rd party csv library handles of these cases.
Comments
Post a Comment