Inserting an inverted exclamation mark into a sqlite table - objective-c

For the life of me I can't figure this out, i've been browsing the web and can't find an answer but also been coding all day so my brain is fried. Currently i'm prepending the inverted exclamation mark to a string like this
NSString *randomString = [NSString stringWithFormat:#"%#random!", #"\u00A1"];
which logs what I want which is
#"¡random!"
So then I insert it into my sqlite database and use the string value given above like so
if(!(self.dbOpen))
{
[self openDatabaseWithSQLName:#"SMCachedDB.db"];
}
sqlInsertStatement = [NSString stringWithFormat:#"INSERT INTO %#(%#) VALUES(%#)", useTable, myColumns, myValues];
char *error;
// Execute statement
if(sqlite3_exec(cachedDatabase, [sqlInsertStatement UTF8String], NULL, NULL, &error) == SQLITE_OK)
{
hasBeenAdded = YES;
NSLog(#"Entry added into '%#' table", useTable);
} else {
NSLog(#"ERROR: %s", sqlite3_errmsg(cachedDatabase));
NSLog(#"ERROR inserting '%#'", myValues);
hasBeenAdded = NO;
}
the string is within the "myValues" string so everything is getting stored correctly but when I select back the values I get the unicode characters before my string like so
"\U00a1random!";
I'm sure I'm missing something dumb. Any help would be greatly appreciated.

I figured it out. It stores the string with the actual unicode characters prepended to it so when I was logging the data stored in the database it returned
"\u00A1random!"
I thought the it would've stored the variable as "¡" and not the actual unicode. So when I selected the value from the database and logged it it returned the value that was necessary which was
"¡random!"
After coming back to it I seemed to figure it out within 5 minutes after spending all that time last night on it, sorry guys.

Related

Objective-C, correctly separate columns in CSV by comma

I have an Excel file that I exported as a CSV file.
Some of the data in the columns also have commas. CSV escapes these by putting the string in the column in quotes (""). However, when I try to parse it in Objective-C, the comma inside the string seperates the data, as if it were a new column.
Here's what I have:
self.csvData = [NSString stringWithContentsOfURL:file encoding:NSASCIIStringEncoding error:&error];
//This is what the data looks like:
//"123 Testing (Sesame Street, Testing)",Hello World,Foo,Bar
//Get rows
NSArray *lines = [self.csvData componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
//Get columns
NSArray *columns = [[lines objectAtIndex:0] componentsSeparatedByString:#","];
//Show columns
for (NSString *column in columns) {
NSLog(#"%#", column);
}
//Console shows this:
"123 Testing (Sesame Street
Testing)"
Hello World
Foo
Bar
Notice how "123 Testing (Sesame Street and Testing)" are output as separate columns. I need these to be one. Any ideas?
Any ideas?
Design an algorithm.
At the start of the input you have one of three possibilities:
You have a " - parse a quoted field
You have a , - handle an empty field
Otherwise - parse a non-quoted field
After parsing if there is any more input left then iterate (loop).
You might start with some variables:
NSUInteger position = 0; // current position
NSUInteger remaining = csvData.length; // left to parse
then enter your loop:
while(remaining > 0)
{
get the next character:
unichar nextChar = [csvData characterAtIndex:position];
Now check if that character is a ", , or something else. You can use an if or a switch.
Let's say it's a comma, then you want to find the position of the next comma. The NSString method rangeOfString:options:range will give you that. The last argument to this method is a range specifying in which part of the string to search for the comma. You can construct that range using NSMakeRange and values derived from position and remaining.
Once you have the next comma you need to extract the field, the substringWithRange: method can get you that.
Finally update position and remaining as required and you are ready for the next iteration.
You'll have to handle a few error cases - e.g. opening quote with no closing quote. Overall it is straight forward.
If you start down this path and it doesn't work ask a new question, showing your code and explaining where you got stuck.
HTH

How to Use An Escape URL String With Formatting in Objective-C

I need to gather data from a website based on the user's input.
searchString is the user inputted value, such as "search this string".
NSString *withoutSpaces = [searchString stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
Here, I need to replace spaces with %20
Next, I need to put the new string without spaces (replaced with %20) into another string.
NSString *unescapedSearchString = [NSString stringWithFormat:
#"website.com/query?=%22%#%22", withoutSpaces];
The site I need is not really "website.com", but that's just an example. I also need the %22 to remain at the beginning and end.
As you can see, I need the %# to format the new withoutSpaces user input into the website URL.
I did a search and found examples but I could not find any with formatting such as in my case using %#.
What's the best way to "escape" the characters and keep my formatted string? Currently, when I try to access data from the website, it comes back as null. However, when I try a string without the %# formatting and an actual value, I successfully retrieve the data from a website.
Any help is greatly appreciated.
You should do things this way:
NSString *searchString = ... // the raw search string with spaces and all
NSString *quoted = [NSString stringWithFormat:#"\"%#\"", searchString];
NSString *escaped = [quoted stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *urlString = [NSString stringWithFormat:#"website.com?query=%#&value=all", escaped];
BTW - the URL seems a little off. There should be a variable name before the = and after the ?.

App Store ID via Appirater different than ID from plist, and apparently random

I'm having an issue with grabbing the App Store ID from my plist, and using it with Appirater. I NSLogged the URL that was being used when the user pushes "Rate Now", and the App Store ID is way different from the App Store ID I set in Info.plist. No idea where it is getting these numbers from -- they are a different set of 9 numbers each time. This is really strange.
The code in Appirater.m that deals with grabbing the App Store ID and using it in the link looks like this: NSString *const kAppiraterAppIdBundleKey = #"AppStoreId";
NSString *templateReviewURL = #"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
....
+ (NSString*)appStoreAppID {
NSString* value = [[[NSBundle mainBundle] infoDictionary] objectForKey:kAppiraterAppIdBundleKey];
NSAssert1(value, #"Error - you have not specified %# property in your info.plist", kAppiraterAppIdBundleKey);
return value;
}
//...
+ (void)rateApp {
//...
NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:#"APP_ID" withString:[NSString stringWithFormat:#"%d", [self appStoreAppID]]];
//...
}
I added a field in the plist called "AppStoreId", and entered the 9 digit code. I made it a string type. Now, the code runs perfectly when I replace "APP_ID" with the actual 9 digit code in that iTunes link above, but when I keep it as APP_ID, I get the error "Cannot connect to the iTunes Store.", and the NSLog output has 9 random numbers in the link, and again, they are different each time.
This is probably an easy fix, but I can't seem to figure it out.
Random numbers? You're using:
[NSString stringWithFormat:#"%d", [self appStoreAppID]]
where appStoreAppID is an NSString.
So you're replacing "APP_ID" with the pointer to the NSString, not the contents of the NSString.
Just use %# instead of %d.

How do I get JSON back from a Sqlite text field?

I've managed to store some JSON to a field in my sqlite database, the length of the TEXT (in the sqlite docs theres no limit on a text field size) field is 1337.
I've even tried varchar, but again my app crashes with SGABRT. I don't get any other error details.
Looking at the record in a sqlite utility the data is complete and fine and my query shown below works.
I've even substituted why query and the code does work with a record in another table.
I know I should be using Core Data but this is an existing app and I can't convert it at this time.
No sure how to proceed ?
NSString *ret = #"";
const char *sql = "select value from MyTable where item = 'json'";
sqlite3 *database;
int result = sqlite3_open(... db path function ...], &database);
... snip in not db and error code ...
sqlite3_stmt *statementTMP;
sqlite3_prepare_v2(database, sql, -1, &statementTMP, NULL);
if (sqlite3_step(statementTMP) == SQLITE_ROW) {
ret = [[NSString alloc] initWithUTF8String:
(char *)sqlite3_column_text(statementTMP, 1)]; << Fails here
}
sqlite3_finalize(statementTMP);
sqlite3_close(database);
EDIT
Start of my JSON data
{"lowestday":"31","pfAppAdvAcSel":-1,"styleselec
Further EDIT
char *test = (char *)sqlite3_column_text(statementTMP, 1);
NSLog(#"value = %s", test); << (NULL)
The problem is that you are calling sqlite3_column_text() incorrectly. Since you are selecting only a single column (value), there is only one column from which you can extract text. In SQLite3, column numbers begin with 0, rather than 1. Therefore, you should change the second argument of your call to sqlite3_column_text with 0 instead of 1.

How to check if [request responseString] is equal to some other string?

For example [request responseString]'s value sent by my servlet to my iphone application is "myinfo". In my iphone application, I made a string like this:
NSString *str = #"myinfo";
then i have if else
if([responseString isEqualToString:str]){
NSLog(#"condition true");
}else{
NSLog(#"condition false");
}
in console its always showing "condition false". Whats the problem? Isn't isEqualToString is write method to check if strings are equal or not? Thanks in advance.
Howwever much you think your two strings are completely equal, they are not. Believe me, if -isEqualToString: did not return YES for two equal strings, somebody would have noticed in the 20 odd years it has been part of the Cocoa API.
I suspect that one of your two strings contains some non printing characters. You might have a line feed or a space or a tab in it. Another possibility (one that I came across recently) is that, for certain character set encodings, you can create an NSString with a nul character in it. If it's at the end, it won't show up. Try logging the lengths of the two strings, or converting them to NSData objects using the UTF16 encoding and logging them.
The NSString method isEqualToString is the correct thing to use here. You can do a sanity check by adding a log to your method:
NSLog(#"responseString = %#",responseString);
NSLog(#"str = %#",str);
if([responseString isEqualToString:str]){
NSLog(#"condition true");
}else{
NSLog(#"condition false");
}
Remember that NSStrings are Case Sensitive, so the two strings must appear exactly the same.
Since you said you're using connectios, sometimes the data retrieved by web is weird, you should first encode the data in a string and then NSLog it to see if it has special characters.
NSString *response = [[NSString alloc] initWithData:dataRetrieved encoding:NSUTF8StringEncoding];
Then you can make sure if your [request responseString] is not getting special chars.
The better way to compare strings in ios:
NSString *responseString = <your string>;
NSString *string2 = <your string>;
if ([responseString caseInsensitiveCompare:string2] == NSOrderedSame) {
//strings are same
} else {
//strings are not same
}