Compare NSString to ameliorate OCR - ios

I'm working on an application in objective C (osX) in which I use an 'OCR' - I use 'Tesseract' which is really good. The problem is, there is some expressions that are not well recognized. In order to get a good result, I would try to make some string comparison and changes.
In other words, my algorithm would look like this :
myNewString = #"tept String";
if ( myNewString isEqualAt80%orMoreToString : #"test String" )
{
myNewString = #"test String";
}
But how could I test if my 'NSString' is at minimum equal at 80% or more than another string ?
Thank you for you help !

Related

How to use this formatter?

(I don't know how to use or what to call this, so I can't think of a better title).
I am using the PNChart classes, specifically PNBarChart. It requires that an array of numbers are given to the yValues.
I need to format this, for which it has PNYLabelFormatter. =
typedef NSString *(^PNYLabelFormatter)(CGFloat yLabelValue);
So when I type the following, what do I fill in the gap with?
[barChart setYLabelFormatter:GAP HERE];
I recognise I need to nest my formatting in this bit, but I don't know what to call this or how to format it.
You can find how to use this lib from examples.
$ pod try PNChat and you'll get demo project.
Open PCChartViewController.m look in block started with
else if ([self.title isEqualToString:#"Bar Chart"]) {
...
self.barChart.yLabelFormatter = ^(CGFloat yValue){
CGFloat yValueParsed = yValue;
NSString * labelText = [NSString stringWithFormat:#"%1.f",yValueParsed];
return labelText;
};
self.barChart setXLabels:#[#"SEP 1",#"SEP 2",#"SEP 3",...];
[self.barChart setYValues:#[#1,#24,#12,#18,#30,#10,#21]];

What is wrong with this NSLocalizableString code?

I have this code on Viewcontroller.m, on Xcode:
NSString *language = NSLocalizedString(#"es", #"language");
NSString *connector = NSLocalizedString(#"de", #"connector to link words");
And this one on the "Localizable.strings (English)":
"language" = "en";
"connector to link words" = "of";
The problem is that with every language I change on the iOs Simulator, I always get the first value, the value of the Viewcontroller.m, instead of get the strings values.
Does anyone know what is wrong?? Thank you so much!
UPDATE:
I have this:
NSString *language = NSLocalizedString(#"es", #"language");
NSString *connector = NSLocalizedString(#"de", #"connector to link words");
But it still doesn't work!! Why????
It only shows the key values!! In the strings I have:
"es" = "en";
"de" = "of";
on the english file, and on the spanish file:
"es" = "es";
"de" = "de";
SOLUTION:
I think I have already done everything right, so the problem must to be in the iOs simulator. If anyone can take advantage of that, my solution has been edit the scheme clicking in the image of the project in the superior task bar, and in the tab "Options" (on the Run part) set "Spanish" as my language by default.
Thanks everybody anyway.
The syntax of NSLocalizedString goes like the below.
NSString * NSLocalizedString(
NSString *key,
NSString *comment
)
The key should be used in your .strings file. The value of the key will be different for different languages .
So when you run the key will be replaced by the value provided in the language .strings file you set.
Look at this tutorial for more explanation.
syntax is NSLocalizedString(key, comment)
And this one on the "Localizable.strings (English)":
"language" = "en";
"connector to link words" = "of";
so "language" is the key and "en" is the value
so
NSString *language = NSLocalizedString(#"language", #"");
NSString *connector = NSLocalizedString(#"connector to link words",#"");

if statements and stringWithFormat

I need to know if there is a way to use if statements to display certain nsstrings, depending on whether or not that NSString contains any data.
I have an nsstringcalled visitorInfo.
The string uses data from other strings (i.e. which operating system the user is running) and displays that info. Here is an example of what I'm talking about:
NSString *visitorInfo = [NSString stringWithFormat:#"INFO\n\nVisitor Location\n%#\n\nVisitor Blood Type\n\%#", _visitor.location, _visitor.bloodType];
And it would display like this:
INFO
Location
Miami, FL
Blood Type
O positive
However, I have several pieces of data that only load if the user chooses to do so. i.e their email address.
This section of code below would do what I want, but my visitorInfo string contains tons of different strings, and if I use this code below, then it won't load any of them if the user chooses not to submit his blood type.
if ([self.visitor.bloodType length] > 0) {
NSString *visitorInfo = [NSString stringWithFormat:#"INFO\n\nVisitor Location\n%#\n\nVisitor Blood Type\n\%#", _visitor.location, _visitor.bloodType];
}
So basically if their is data stored in bloodType then i went that code to run, but if there isn't any data I only want it to skip over bloodType, and finish displaying the rest of the data.
Let me know if you have any more questions
Additional details. I'm using an NSString for a specific reason, which is why I'm not using a dictionary.
Just build up the string as needed using NSMutableString:
NSMutableString *visitorInfo = [NSMutableString stringWithFormat:#"INFO\n\nVisitor Location\n%#, _visitor.location];
if ([self.visitor.bloodType length] > 0) {
[visitorInfo appendFormat:#"\n\nVisitor Blood Type\n\%#", _visitor.bloodType];
}
You can check if a string has any data in it by using the following
if([_visitor.location length]<1){
//This means there's no data and is a better way of checking, rather than isEqualToString:#"".
}else{
//there is some date here
}
** EDIT - (just re-reading your question, sorry this answer is dependant on _visitor.location being a string in the first place)*
I hope this helps
Try this -
NSString *str = #"INFO";
if (_visitor.location) {
str = [NSString stringWithFormat:#"\n\nVisitor Location\n%#",_visitor.location];
}
if (_visitor.bloodType) {
str = [NSString stringWithFormat:#"\n\nVisitor Blood Type\n\%#",_visitor.bloodType];
}

Converting int to NSString

I thought I had nailed converting an int to and NSString a while back, but each time I run my code, the program gets to the following lines and crashes. Can anyone see what I'm doing wrong?
NSString *rssiString = (int)self.selectedBeacon.rssi;
UnitySendMessage("Foo", "RSSIValue", [rssiString UTF8String] );
These lines should take the rssi value (Which is an NSInt) convert it to a string, then pass it to my unity object in a format it can read.
What am I doing wrong?
NSString *rssiString = [NSString stringWithFormat:#"%d", self.selectedBeacon.rssi];
UPDATE: it is important to remember there is no such thing as NSInt. In my snippet I assumed that you meant NSInteger.
If you use 32-bit environment, use this
NSString *rssiString = [NSString stringWithFormat:#"%d", self.selectedBeacon.rssi];
But you cann't use this in 64-bit environment, Because it will give below warning.
Values of type 'NSInteger' should not be used as format arguments; add
an explicit cast to 'long'
So use below code, But below will give warning in 32-bit environment.
NSString *rssiString = [NSString stringWithFormat:#"%ld", self.selectedBeacon.rssi];
If you want to code for both(32-bit & 64-bit) in one line, use below code. Just casting.
NSString *rssiString = [NSString stringWithFormat:#"%ld", (long)self.selectedBeacon.rssi];
I'd like to provide a sweet way to do this job:
//For any numbers.
int iValue;
NSString *sValue = [#(iValue) stringValue];
//Even more concise!
NSString *sValue = #(iValue).stringValue;
NSString *rssiString = [self.selectedBeacon.rssi stringValue];
For simple conversions of basic number values, you can use a technique called casting. A cast forces a value to perform a conversion based on strict rules established for the C language. Most of the rules dictate how conversions between numeric types (e.g., long and short versions of int and float types) are to behave during such conversions.
Specify a cast by placing the desired output data type in parentheses before the original value. For example, the following changes an int to a float:
float myValueAsFloat = (float)myValueAsInt;
One of the rules that could impact you is that when a float or double is cast to an int, the numbers to the right of the decimal (and the decimal) are stripped off. No rounding occurs. You can see how casting works for yourself in Workbench by modifying the runMyCode: method as follows:
- (IBAction)runMyCode:(id)sender {
double a = 12345.6789;
int b = (int)a;
float c = (float)b;
NSLog(#"\ndouble = %f\nint of double = %d\nfloat of int = %f", a, b, c);
}
the console reveals the following log result:
double = 12345.678900
int of double = 12345
float of int = 12345.000000
original link is http://answers.oreilly.com/topic/2508-how-to-convert-objective-c-data-types-within-ios-4-sdk/
If self.selectedBeacon.rssi is an int, and it appears you're interested in providing a char * string to the UnitySendMessage API, you could skip the trip through NSString:
char rssiString[19];
sprintf(rssiString, "%d", self.selectedBeacon.rssi);
UnitySendMessage("Foo", "RSSIValue", rssiString );

Poor compiler warnings

how to get rid of the compiler warning in XCode 5.1
in Stringtable is of course a string with a format specifier (updated: now in front of code)
"fmtDetail" = "Count: %d";
int number = 0;
//Compiler warning: Data argument not used by format string
NSString *text = [NSString stringWithFormat:NSLocalizedString(#"fmtDetail", nil), number];
//this gets no warning
NSString *fmtDetail = NSLocalizedString(#"fmtDetail", nil);
NSString *text2 = [NSString stringWithFormat:fmtDetail, number];
It is not the compiler warning that is poor - you should correct your code.
There seems to be an %d (or similar) missing in the #"fmDetail".
Or you should get rid of the number argument - that is not used.
Depends on what you are actually trying to do...
NSString *text = [NSString stringWithFormat:NSLocalizedString(#"fmtDetail%d", nil), number];
NSString *text = [NSString stringWithFormat:NSLocalizedString(#"fmtDetail %d", nil), number];
NSString *text = [NSString stringWithString:NSLocalizedString(#"fmtDetail", nil)];
Second note: this #"fmtDetail%d" should match the key in the plist dictionary (translated strings). It could also be simly #"theDeatils" - the string that returned from your plist is the one that should actually hold formatting data for the string.
Why would one want to use the %d in the key? Because NSLocalizedString returns the key as the result if it doesn't find string with appropriate key.
EDIT: MartinR found the real reason for why this warning appears. Just a note that might be useful: since localizing strings usually means translation into many languages (duh) you might need to use numbered placeholders - not all languages share the same basic sentence structure.
This seems to be not a bug, but a new feature of the compiler that comes with Xcode 5.1 (beta). It expects now that in
[NSString stringWithFormat:NSLocalizedString(key, ...), arguments... ]
the key itself is a valid format for the given arguments.
(In other words, the key uses the same format specifiers as its value from the strings file).
For example:
// Source code:
[NSString stringWithFormat:NSLocalizedString(#"Count = %d", nil), number]
// Localizable.strings:
"Count = %d" = "Die Anzahl ist %d";
This is an advantage because the compiler can now check that the number and types
of the format specifiers match the actual arguments even with localizable format
strings. That was not possible before (as far as I know).
For example, this will cause a warning in Xcode 5.1 beta, but not in Xcode 5.0.2:
[NSString stringWithFormat:NSLocalizedString(#"fmtDetail %f", nil), 13];
// warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
(And as #rokjarc already had pointed out, using a valid format string as key makes
sense anyway, because NSLocalizedString() returns the key if no matching string
is found in the Localizable.strings file.)

Resources