ios - CSV Not Formatted Correctly -


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)     } 

enter image description here

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:

  1. 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).
  2. 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