ios blocks with different parameters - ios

Iam completely new to ios Blocks and have no idea about the syntax .Iam trying to create a block which takes two parameter one an int and another a NSString and returns an int value. Iam getting error and don't know how to proceed help me with some tutorial or guide me through this is the block .
int (^indexFinder)(int , NSString *) = int (^(int passedValue , NSString * passedText) {};

Do like this:
int (^indexFinder)(int , NSString *) = ^(int a, NSString * b) {
return 10 ;
} ;
int i = indexFinder(1, #"") ;
NSLog(#"%d", i) ;
I learn it from Blocks programming topic

should be like this:
int (^indexFinder)(int , NSString *) = ^int (int passedValue , NSString * passedText) {
NSLog(#">> %d %#",passedValue,passedText);
return 0;
};
indexFinder(0,#"hello");
here are some links that tackles about block: link1, link2

Related

How to call C function from Objective-C

I'm currently trying to convert videos on iOS using FFmpeg.
I've modified their example in transcoding.c according to my needs.
How do I actually call the following function from Objective-C:
int mainFunction(int argc, char **argv);
I'm not sure on how to provide the arguments from Objective-C.
Any help would greatly be appreciated.
Objective-C is a superset of C. All you need to do is call it from your Objective-C code.
char* args[] = { "foo", "bar", NULL }; // Might need the NULL to emulate command line arguments.
int result = mainFunction(2, args);
You could pass argc and argv directly from your own main
int main(int argc, char** argv)
{
int result = mainFunction(argc, argv);
}
If your arguments are in an array of NSStrings, you'll need to convert them to a normal C array of C strings:
char** cStringArray = malloc(([stringArray count] + 1) * sizeof(char*));
for (int i = 0 ; i < [stringArray count] ; ++i)
{
NSString* aString = [stringArray objectAtIndex: i];
cStringArray[i] = [aString UTF8String];
}
cStringArray[[stringArray count]] = NULL;
int result = mainFunction([stringArray count], cStringArray);
free(cStringArray);
It's a long time since I last did any Objective-C, so apologies for any syntax errors.

Converting very large NSDecimal to string eg. 400,000,000,000 -> 400 T and so forth

I am making a game that requires me to use very large numbers. I believe I am able to store very large numbers with NSDecimal. However, when displaying the numbers to users I would like to be able to convert the large number to a succinct string that uses characters to signify the value eg. 100,000 -> 100k 1,000,000 -> 1.00M 4,200,000,000 -> 4.20B and so forth going up to extremely large numbers. Is there any built in method for doing so or would I have to use a bunch of
NSDecimalCompare statements to determine the size of the number and convert?
I am hoping to use objective c for the application.
I know that I can use NSString *string = NSDecimalString(&NSDecimal, _usLocale); to convert to a string could I then do some type of comparison on this string to get the result I'm looking for?
Use this method to convert your number into a smaller format just as you need:
-(NSString*) suffixNumber:(NSNumber*)number
{
if (!number)
return #"";
long long num = [number longLongValue];
int s = ( (num < 0) ? -1 : (num > 0) ? 1 : 0 );
NSString* sign = (s == -1 ? #"-" : #"" );
num = llabs(num);
if (num < 1000)
return [NSString stringWithFormat:#"%#%lld",sign,num];
int exp = (int) (log(num) / 3.f); //log(1000));
NSArray* units = #[#"K",#"M",#"G",#"T",#"P",#"E"];
return [NSString stringWithFormat:#"%#%.1f%#",sign, (num / pow(1000, exp)), [units objectAtIndex:(exp-1)]];
}
Some sample examples:
NSLog(#"%#",[self suffixNumber:#99999]); // 100.0K
NSLog(#"%#",[self suffixNumber:#5109999]); // 5.1M
Source
Solved my issue: Can only be used if you know that your NSDecimal that you are trying to format will only be a whole number without decimals so make sure you round when doing any math on the NSDecimals.
-(NSString *)returnFormattedString:(NSDecimal)nsDecimalToFormat{
NSMutableArray *formatArray = [NSMutableArray arrayWithObjects:#"%.2f",#"%.1f",#"%.0f",nil];
NSMutableArray *suffixes = [NSMutableArray arrayWithObjects:#"k",#"M",#"B",#"T",#"Qa",#"Qi",#"Sx",#"Sp",#"Oc",#"No",#"De",#"Ud",#"Dud",#"Tde",#"Qde",#"Qid",#"Sxd",#"Spd",#"Ocd",#"Nvd",#"Vi",#"Uvi",#"Dvi",#"Tvi", nil];
int dick = [suffixes count];
NSLog(#"count %i",dick);
NSString *string = NSDecimalString(&nsDecimalToFormat, _usLocale);
NSString *formatedString;
NSUInteger characterCount = [string length];
if (characterCount > 3) {
NSString *trimmedString=[string substringToIndex:3];
float a;
a = 100.00/(pow(10, (characterCount - 4)%3));
int remainder = (characterCount-4)%3;
int suffixIndex = (characterCount + 3 - 1)/3 - 2;
NSLog(#"%i",suffixIndex);
if(suffixIndex < [suffixes count]){
NSString *formatSpecifier = [formatArray[remainder] stringByAppendingString:suffixes[suffixIndex]];
formatedString= [NSString stringWithFormat:formatSpecifier, [trimmedString floatValue] / a];
}
else {
formatedString = #"too Big";
}
}
else{
formatedString = string;
}
return formatedString;
}

Objective C Message Argument Array Parsing (AJNMessageArgument)

I'm working with AllJoyn on iOS using objective C. I'm having trouble parsing an ALLJOYN_ARRAY type in objective C. The problem is that the MsgArg type (C++) is abstracted through the AJNMessagArgument type (objective c). The sample code for parsing an array signature of "a{iv}" in c++ is as follows:
MsgArg *entries;
size_t num;
arg.Get("a{iv}", &num, &entries);
for (size_t i = 0; i > num; ++i) {
char *str1;
char *str2;
uint32_t key;
status = entries[i].Get("{is}", &key, &str1);
if (status == ER_BUS_SIGNATURE_MISMATCH) {
status = entries[i].Get("{i(ss)}", &key, &str1, &str2);
}
}
Now in objective c, the msgarg is the handle of the AJNMessageArgument type. I've tried the following to try getting this to work with no avail:
AJNMessageArgument *strings = [AJNMessageArgument new];
size_t numVals;
QStatus status = [supportedLangsArg value: #"as", &numVals, strings.handle];
if(status != ER_OK){
NSLog(#"ERROR: Could not supported languages from the message argument");
}
This returns ER_OK, but I can't see any data in the handle via the debugger like I can with valid AJNMessageArguments.
Passing in &strings.handle throws a compile error "Address of property expression required".
I've tried quite a few other things, but none make much sense compared to the one above.
Please help me! I need an example of how to parse an "as" signature in objc. I haven't been able to find any docs for this.
Thanks for any help!
Ok, short story is this can't be done without adding custom code to the AJNMessageArgument Class. This is because in this scenario, the "value" method will return a pointer to an array of MsgArg types. Objective C cannot interact with MsgArg - Which is the whole reason they created the AJNMessageArgument wrapper for Objective C.
Here is how it is done:
Add this static method to your AJNMessageArgument.mm class:
+ (NSArray*)getAJNMessageArgumentArrayFromMsgArgArray:(void*)arg : (int)size
{
NSMutableArray * toReturn = [NSMutableArray new];
MsgArg *msgArray = (MsgArg*) arg;
for (int i = 0; i < size; ++i)
{
void * msarg = malloc(sizeof(MsgArg));
MsgArg arg = msgArray[i];
memcpy(msarg, &msgArray[i], sizeof(MsgArg));
AJNMessageArgument *toAdd = [[AJNMessageArgument alloc] initWithHandle:msarg];
[toReturn addObject:toAdd];
}
return [toReturn copy];
}
Don't forget to add the method definition to the AJNMessageArgument.h file:
+ (NSMutableArray*)getAJNMessageArgumentArrayFromMsgArgArray:(void*)arg : (int)size
So now, in our objective C code, we can parse the AJNMessageArgument with signature "as" - but we can't cast it to the MsgArg type yet because we can't access that structure outside of objc++ - so we will use a (void *).
+ (NSArray*)getSupportedLangsFromMessageArgument:(AJNMessageArgument*)supportedLangsArg
{
void *strings; //void * to keep track of MsgArg array data.
size_t numVals;
QStatus status = [supportedLangsArg value: #"as", &numVals, &strings];
if(status != ER_OK){
NSLog(#"ERROR: Could not supported languages from the message argument");
}
NSMutableArray *arrayOfMsgArgs = [AJNMessageArgument getAJNMessageArgumentArrayFromMsgArgArray:strings :numVals];
//Now loop through the resulting AJNMessageArguments of type ALLJOYN_STRING - and parse out the string.
NSMutableArray *arrayOfStrings = [NSMutableArray new];
for (AJNMessageArgument *arg in arrayOfMsgArgs) {
NSString* msgArgValue = [AboutUtil getStringFromMessageArgument:arg];
[arrayOfStrings addObject:msgArgValue];
}
return [arrayOfStrings copy];
}
Now we have an NSArray of NSStrings. Whew.
In case you were wanting to see the code to get the NSString out of the AJNMessageArguments that are in the array, here is that method:
+ (NSString*)getStringFromMessageArgument:(AJNMessageArgument*)msgarg
{
char *charStr;
QStatus status = [msgarg value:#"s", &charStr];
if (status != ER_OK) {
NSLog(#"Error");
}
NSString *str = [NSString stringWithFormat:#"%s", charStr];
return str;
}
Happy AllJoyn-ing.

Chinese character to ASCII or Hexadecimal

Im struggling to covert chinese word/characters to ascii or hexadecimal and all the values I've got up until now is not what I was suppose to get.
Example of conversion is the word 手 to hex is 1534b.
Methods Ive followed till now are as below, and I got varieties of results but the one I was looking for,
I really appreciate if you can help me out on this issue,
Thanks,
Mike
- (NSString *) stringToHex:(NSString *)str{
NSUInteger len = [str length];
unichar *chars = malloc(len * sizeof(unichar));
[str getCharacters:chars];
NSMutableString *hexString = [[NSMutableString alloc] init];
for(NSUInteger i = 0; i < len; i++ )
{
[hexString appendFormat:#"%02x", chars[i]]; //EDITED PER COMMENT BELOW
}
free(chars);
return hexString;}
and
const char *cString = [#"手" cStringUsingEncoding:NSASCIIStringEncoding];
below is the similar code in Java for Android, Maybe it helps
public boolean sendText(INotifiableManager manager, String text) {
final int codeOffset = 0xf100;
for (char c : text.toCharArray()) {
int code = (int)c+codeOffset;
if (! mConnection.getBoolean(manager, "SendKey", Integer.toString(code))) {
}
Your Java code is just doing this:
Take each 16-bit character of the string and add 0xf100 to it.
If you do the same thing in your above Objective-C code you will get the result you want.

How do I compare characters in custom sqlite collation in objective-c?

I went through lots of questions here on SO (like this one) but I still need some assistance.
I need my sqlite select to order by slovenian alphabet (letter č comes after c, letter š after s and letter ž after z).
Here is the code I use:
static int sqlite3SloCollate(void * foo, int ll, const void *l, int rl,
const void *r){
NSString *left = [NSString stringWithCharacters:l length:ll];
NSString *right = [NSString stringWithCharacters:r length:rl];
//THIS IS WHERE I DON'T KNOW HOW TO COMPARE CHARACTERS
NSComparisonResult rs = [left compare:right options:NSForcedOrderingSearch];
return rs;
}
sqlite3_create_collation(database, "SLOCOLLATE", SQLITE_UTF8, NULL, &sqlite3SloCollate);
querySQL = [NSString stringWithFormat: #"SELECT s.id FROM lyrics l INNER JOIN song s ON (l.idSong=s.id) WHERE content LIKE '%%%#%%' GROUP BY s.id ORDER BY s.title COLLATE SLOCOLLATE;",searchString];
Which NSOrdering type should I use? Or do I have to write my own compare function (can you give me an example)?
I think that this function might help you :
- (NSComparisonResult)compare:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)range locale:(id)locale
(From Apple documentation).
You can create a locale using :
- (id)initWithLocaleIdentifier:(NSString *)string
(From Apple NSLocale Class Documentation).
This code should do the trick :
NSRange range = NSMakeRange(0, [left length]);
id locale = [[NSLocale alloc] initWithLocaleIdentifier:#"sl_SI"];
NSComparisonResult rs = [left compare:right options:NSForcedOrderingSearch range:range locale:locale];
I hope this will help.
The #DCMaxxx answer has most of it. Plus the comment that you need to use stringWithUTF8String. But there's some more issues.
1) stringWithUTF8String uses null-terminated c-strings, whilst sqlite is suppling strings with just a length and no null termination.
2) For the number of characters to compare, we need to take the shortest length, not just the left length.
3) When the comparison is equal for the compare, we then need to consider which string is longer.
Full code here. I use an NSMutableData object to convert length coded strings to null terminated strings. It's probably quicker and easier to do it with straight c code, if you are that way inclined.
static int sqlite3SloCollate(void * foo, int ll, const void *l, int rl,
const void *r){
NSMutableData* ld = [NSMutableData dataWithBytes:l length:ll+1];
[ld resetBytesInRange:NSMakeRange(ll, 1)];
NSString *left = [NSString stringWithUTF8String:[ld bytes]];
NSMutableData* rd = [NSMutableData dataWithBytes:r length:rl+1];
[rd resetBytesInRange:NSMakeRange(rl, 1)];
NSString *right = [NSString stringWithUTF8String:[rd bytes]];
NSRange range = NSMakeRange(0, MIN([left length],[right length]));
id locale = [[NSLocale alloc] initWithLocaleIdentifier:#"sl_SI"];
NSComparisonResult result = [left compare:right options:0 range:range locale:locale];
if (result==NSOrderedSame) {
if (ll>rl) {
result = NSOrderedDescending;
} else if (ll<rl) {
result = NSOrderedAscending;
}
}
// NSLog(#"Comparison:%# - %# - %li",left,right,(long)result);
return result;
}

Resources