Swift generate CSV with comma [duplicate] - ios

There seem to be other answers the this on stack overflow but nothing that is specific to swift.
I am generating a CSV from an Site Object containing 3 properties
Struct SiteDetails {
var siteName:String?
var siteType: String?
var siteUrl: String?
}
The problem is that siteName may contain a comma so its making it really hard to convert back from CSV into a object when I read the CSV file back as some lines have 4 or more CSV elements.
Here is the code I am using to export to CSV:
func convertToCSV(sites: [SiteDetails]) -> String {
var siteAsCSV = ""
siteAsCSV.appendContentsOf("siteName,siteType,siteUrl\n")
for site in sites {
siteAsCSV.appendContentsOf("\(site.siteName),\(site.siteType),\(site.siteUrl)\n")
}
}
Any ideas how to stop this extra comma issue?

The CSV specification suggests to wrap all fields containing special characters in double quotes.

I managed to get this working using the modification of adding the double quotes to each field. In Swift, this requires you to escape the quotation mark which looks like its not going to run when you look at Xcode's syntax highlighting, but it works fine.
func convertToCSV(sites: [SiteDetails]) -> String {
var SiteAsCSV = ""
SiteAsCSV.appendContentsOf("siteName,siteType,siteUrl\n")
for site in sites {
SiteAsCSV.appendContentsOf("\"\(site.SiteName)\",\"\(site.Sitetype)\",\"\(site.SiteUrl)\"\n")
}
}

Related

Swift 4 OutputStream produces more output than input

I have been attempting to use streams in swift to interface with a java socket server (I don't believe the java server is my problem) but when I attempt to write with an OutputStream my string includes a bunch of extra garbage that was not in my original string
The code currently looks like this:
var maxWriteLength = 4096
func sendMessage(msg: String) {
let encodedDataArray = [UInt8](msg.utf8)
outputStream.write(encodedDataArray, maxLength: maxWriteLength)
}
However when I give it an input of "hi" it returns an ouput of:
Echo: hi���8B��,rؾ�؇��allowCloudBackup؇��allowAppInstallation؇��safariForceFraudWarning�&��q���ޙTh�C��=wthread��&��q����������������8$��N��8$���0'}��#�
Echo: �'��q����������p�g�iYh�C���iYh�C��
Echo: D�#D�8״
Echo: pV���؇��requireAlphanumeric؇��allowCellularHDUploadsInternational-Key_2��
and much much more
I have seen other posts suggesting that you should use encodedDataArray.count instead of a maxWriteLength however when I have used this the OutputStream will not write anything.
Thanks in advance.
For future people who struggle with this it was indeed the way the server was handling messages (I went back to check it). The problem was that I was using Scanner.nextLine() and had no \n inside of the swift portion of my code. If you are using an array make sure that you add + "\n" to your string before it is made into an array otherwise the bytes for \n will not be written. The final code looked like this:
func sendMessage(msg: String) {
var finalMsg = msg + "\n"
let encodedDataArray = [UInt8](finalMsg.utf8)
outputStream.write(encodedDataArray, maxLength: encodedDataArray.count)
}

ios application Localization

How can I set ios application supported languages?
e.g I use NSDate to get current day. If the device language is other than my supported languages NSDateFormatter returns "day" in device's language but I want to get in English if I don't support that language.
I know there is a way to get day in specific language using NSLocal but I don't want to do that way because I need to convert other strings as well.
The Apple documentation covers this pretty clearly. I know all you need is the word "day", but the following will help you include any word for any language if you do as follows:
1) You need to place all of the words (Strings) in your application into a single .swift file. Each word should be returned in a function that converts this string into the localized string per the device's NSLocal set in the device settings:
struct Localization {
static let all: String = {
return getLocalized("All")
}()
static let allMedia: String = {
return getLocalized("All Media")
}()
static let back: String = {
return getLocalized("Back")
}()
// ...and do this for each string
}
2) This file should also contain a static function that will convert the string:
static func getLocalized(_ string: String) -> String {
return NSLocalizedString(string, comment: "")
}
Here, the NSLocalizedString( method will do all of the heavy lifting for you. If will look into the .XLIFF file (we will get to that) in your project and grab the correct string per the device NSLocale. This method also includes a "comment" to tell the language translator what to do with the "string" parameter you passed along with it.
3) Reviewing all of the strings that you placed in your .swift file, you need to include each of those into an .XLIFF file. This is the file that a language expert will need to go over and include the proper translated word per string in the .XLIFF. As I stated before, this is the file that once included inside your project, the NSLocalizedString( method will search this file and grab the correct translated string for you.
And that's it!

URL Mapping - Replacing characters in a parameter pulled from a database

I am currently trying to figure out, how to modify the parameter being integrated into the URL Mapping I am using.
static mappings =
{
"/$controller/$action?/$id?/(.$format)?"
{
constraints {
// apply constraints here
}
}
name test1: "/.../$title/..."{
controller = "study"
action = "st_show"
}
name test2: "/.../$title/..."{
controller = "search"
action = "se_show"
}
The parameter $title is pretty much a dataset, which is pulled from a database and which will get transmitted in the following format [ this is a title ]. So there are square brackets in front and behind the string and words are seperated through blanks.
If I am creating a link through g:link now with the params nested in, it gets put into the url as it is pulled from the database. What I am attempting is to create SEO-URLs, which will present a certain title of a publication devided by hyphens instead of url-encoded "%20".
Until now, I was able to generate dynamic urls looking like this:
http://localhost:8080/projectname/show/%5BAllgemeine%20Bevölkerungs[...]/782/...PARAMS...
Furthermore I already implemented it through JQuery, though it should be static and users should be able to copy the link to open up the page themselves - that wouldn't be possible when changing the url client-side while loading up the page.
Is there a way to define a function with something like replaceAll.(' ', '-'), which can be invoked onto the parameter in the mapping to replace blanks with hyphens and f.e. square brackets with an empty character?
That's pretty much, what I wasn't able to come by through the documentation.
Thank you already in advance for your help!
I managed to solve my problem by creating a service with a function containing a regex and executing this function onto the parameter title in my g:link, which I firstly converted to a string, which gets passed to the function.
<g:link controller="study" action="st_show" params="[data: data, ... title: ConversionService.convert(fieldValue(bean: path).toString(), ... data: data)]"></g:link>
And the function in the ConversionService
public static String convert(String title){
title = title.replaceAll("\\s", "-").replaceAll("[^0-9a-zA-Z\\-]", "");
return title;
}

Replacing html text with parameters in url?

I have the url parmeters http://www.nositeinparticular.coom/product1?test=brand&old=Superman&new=Batman.
I was wanting to know the proper way to use javascript to do the following;
Look to see if test=brand
If it does replace all the values of old with the value of new, ie replacing the word Superman with Batman.
I have this so far to see if test equals brand:
$(document).ready(function() {
var url = location.pathname;
if (url.indexOf("test=brand")) {
}
How would I go about parsing the values from the url and running the replacment?

NSString to NSDictionary

I have a string (from HTTP Header) and want to split it into a dictionary.
foo = \"bar\",baz=\"fooz\", beta= \"gamma\"
I ca not guarantee that the string is the same every time. Maybe there are spaces, maybe not, sometimes the double quotes are escaped, sometimes not.
So I found the solution in PHP with regular expressions. Unfortunately I can't convert it to work on iOS.
preg_match_all('#('.$key.')=(?:([\'"])([^\2]+?)\2|([^\s,]+))#', $input, $hits, PREG_SET_ORDER);
foreach ($hits as $hit) {
$data[hit[1]] = $hit[3] ? $hit[3] : $hit[4];
}
Can anybody help me converting this to Objective-C?
I met a guy which is kinda RegEx guru. He explained the whole stuff and I got the following (working!!!!) solution in RegEx.
This gives me strings like foo="bar":
(?<=[,\\s])((realm|qop|nonce|opaque)=(?:([\"'])([^\2]+?)\2|([^\\s,]+)))
I then use another RegEx to split it by key and value to create a dictionary.

Resources