(Objective C) Obtain CFstringRef from NSMutableArray - iphone

I have an NSMutableArray that was downloaded via FTP. The elements in the array are CFFTPStream resource constants that are of type CFStringRef.
I would like to create a String from the "kCFFTPResourceName" constant. However being new to Objective C and iphone development I am struggling.
Everything that I have done has resulted in ARC throwing a fit or errors like:
2013-01-03 15:31:44.874 Street Light Reporter[1382:11603] -[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x6e1e930
2013-01-03 15:31:44.875 Street Light Reporter[1382:11603] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x6e1e930'
My most recent attempt is:
CFStringRef *c = [ar objectAtIndex:4];
which doesnt work for the following two reasons:
Incompatible pointer types initializing 'CFStringRef *' (aka 'const struct __CFString **') with an expression of type 'id'
AND
Implicit conversion of an Objective-C pointer to 'CFStringRef *' (aka 'const struct __CFString **') is disallowed with ARC
I have tried all sorts of typecasting and messing around with (__bridge) and whatnot and I have had no luck.
Can anybody help me out here? Any help will be appreciated.

CFStringRef is a pointer already, you don't need the star. Also, you can cast CFStringRef to NSString and it will work fine and will be easier to work with. This is called toll free bridging. If you still need the CFStringRef:
ARC:
CFStringRef c = (__bridge CFStringRef)([ar objectAtIndex:4]);
Non arc
CFStringRef c = (CFStringRef)([ar objectAtIndex:4]);

You have two errors here: the first and the most severe one is that your ar object is a NSDictionary not a NSArray. That's why performing
CFStringRef *c = [ar objectAtIndex:4];
you are getting a NSInvalidArgumentException. objectAtIndex: is a method of NSArray that you are sending to a NSdictionary instance.
The second error is the cast. As Fernando already pointed out, you need to cast it using the __bridge keyword like follows.
CFStringRef c = (__bridge CFStringRef)([ar objectAtIndex:4]);
so that ARC will know that you are now treating that object as a C pointer.
Note also that CFStringRef is defined as
typedef const struct __CFString * CFStringRef;
so it's already a pointer and you have to get rid of the *.

It seems that you get an CFDictionary back and not an array.
The constants you linked to are keys for the dictionary, with which you can access the values.

Related

NSDecimalNumber.adding from NSManagedObjects hitting unrecognized selector issue

First, let me thank everyone in the SO community in advance for your help in getting me out of this jam.
My app hits a runtime error, and I've isolated the line causing the error.
When I attempt to add two NSDecimalNumber variables use the .adding method, I receive this "unrecognized selector sent to instance" error:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSCFNumber
decimalNumberByAdding:]: unrecognized selector sent to instance
0x608002c361a0'
I've created dummy NSDecimalNumber variables to try and debug this issue, and they seem to work fine when adding. However, when working with my NSManagedObject variables (result and newTransaction) which have NSDecimalNumber variables, I run into this error.
Below is the code that is causing these issues:
//Testing with dummy variables
let a1 = NSDecimalNumber(decimal: 5.2)
let a2 = NSDecimalNumber(decimal: 10.8)
print ("a1: \(a1), a2: \(a2)") //a1: 5.2, a2: 10.8
let a3 = a1.adding(a2)
print ("a3: \(a3)") //a3: 16
//Great, everything above works fine.
//Now let's try using my NSManagedObjects, which were defined in another section
let a = result.netChange //result.netChange is of class NSDecimalNumber
let b = newTransaction.amount //newTransaction.amount is of class NSDecimalNumber
print ("a: \(a), b: \(b)") //a: 444.12, b: 22.23
let c = a.adding(b) //<---This is where the app crashes
print ("c: \(c)") //Does not print, as the app has stopped
My question: Why are my dummy variables able to add with each other, while my NSManagedObject variables cannot?
Thanks again!
A core data property of type "Double" is stored as NSNumber in the
managed object context. It is not sufficient to change the type in the
NSManagedObject subclass because the accessor methods are created
dynamically at runtime. Your code compiles, but crashes at runtime
because the variable is a NSNumber and not a NSDecimalNumber.
The solution is to set the type to "Decimal" in the Core Data model
inspector.

Getting an error when using replaceOccuranceOfString function

[str replaceOccurrencesOfString: withString: options: range:
[str replaceOccurrencesOfString:#"'" withString:#"!~" options:0 range:NSMakeRange(0,str.length)]
I am using this function to replace ' symbol in my NSMutableString with !~ symbol so that I can store that string into database. Its working fine when I stored it into database, but at the time of retrieving and convert it back using same function it showing me error like.
Error
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with replaceOccurrencesOfString:withString:options:range:'
Here, str is of NSMutableString type. I checked for its type [str class] its converts to NSCFString don't know why its changing? I also try to convert it to NSMutableString, but its not converting. I am trying for it for so many times in some other ways, but its working fine with all other places, only in my one view controller, it showing me this.
Any guesses where's I am doing wrong?
You don't show how you are converting the immutable from the data base to a mutable string. Just doing NSMutableString *mstr = str; isn't enough, you'd need to use NSMutableString *mstr = [NSMutableString stringWithString:str];.
Because the returned string is immutable you might want to consider using [NSString stringByReplacingOccurrencesOfString:withString:] instead of working with mutable strings.

XCODE incompatible pointer type error

I am getting a casting error. My app is reading a text file from a webpage using 'stringWithContentsOfURL' method. I want to parse the individual lines into separate components. This is a snippet of the code.
int parameterFive_1 = 0;
parameterFive_1_range = NSMakeRange(0,10)
lines = [response componentsSeparatedByString:#"\r"];
parameterFive_1 = CFStringGetIntValue([[lines objectAtIndex:i] substringWithRange:parameterFive_1_range]);
I am getting the following error message:
" Implicit conversion of an Objective-C pointer to 'CFStringRef' (aka 'const struct __CFString *') is disallowed with ARC"
I thought it might be the compiler option but changing it to the default is not making a difference. Can anyone provide any insight?
Just cast the NSString* to CFStringRef to satisfy ARC:
parameterFive_1 = CFStringGetIntValue((__bridge CFStringRef)[[lines objectAtIndex:i] substringWithRange:parameterFive_1_range]);
The __bridge keyword here lets ARC know that it doesn't need to transfer ownership of the string.

Objective-C: NSMutableString replaceCharactersInRange raising Exception

I expected this code to replace the hate with some love.
NSMutableString *teststring=#"I hate programming my iPhone";
NSString *overwriteSource=#"love";
NSRange temprange=NSMakeRange(2, 4);
[teststring replaceCharactersInRange:temprange withString:overwriteSource];
NSLog(#"%#",teststring);
This terminates due to an uncaught exception and I can't figure out why. Help ! (and thanks)
In your first line, you're attempting to assign an NSString * (#"I hate...") to an NSMutableString * (teststring).
Your original code should give you a compilation warning:
incompatible Objective-C types
initializing 'struct NSString *',
expected 'struct NSMutableString *'
The following will allow your code sample to compile and run correctly:
NSMutableString *teststring=[NSMutableString stringWithString:#"I hate programming my iPhone"];

Obj-C: Difference between "Fairfield" and #"Fairfield" (with at string)?

I just had a ridonkulous typo in my iPhone app, answered here.
Now I'm wondering about the #"..." notation.
why this works:
NSArray *someArray = [NSArray arrayWithObjects: #"Fairfield", nil];
and this does not (even though it compiles, it will throw an EXC_BAD_ACCESS):
NSArray *someArray = [NSArray arrayWithObjects: "#Fairfield", nil];
Edit:
Ok, so you guys have pointed out that I can't add a C string to an NSArray, because it's obviously not an object.
Now another question: Isn't this somewhat of an oversight? I mean, why does the "...WithObjects:" message specify a list of (id) instead of (NSObject *)?
"#Fairfield" is a normal C string with an '#' character in it. #"Fairfield" is an Objective-C string (NSString on OS X) with no literal '#' in it.
You cannot add C strings to Cocoa collections.
It accepts id rather than NSObject because all initialisers return id. All initialisers return id because subclasses would otherwise override the return type of their ancestors' initialisers.
For example, -[NSMutableString init] can't return NSMutableString * because it subclasses -[NSString init], which can't return NSString * because it overrides -[NSObject init].
Unfortunately, implicit type-casting between const char * and id is perfectly legit, so the compiler won't throw a warning, however a static analyser may be able to pick this sort of mishap up fairly easily.
"Fairfield" is a C string, #"Fairfield" is an Objective-C string.
#"Fairfield" is an object (NSString), so you can send it methods ([#"Fairfield" uppercaseString]) and add it to Objective-C arrays ([NSArray arrayWithObjects:#"Fairfield",nil]). You can only add objects to NSArrays.
On the other hand, "Fairfield" is a C string, and is generally not used in Cocoa. For the most part, you can get by with only using #"Fairfield"
The other reason that a number of things in Cocoa deal with id rather than NSObject* is because, unlike some other languages (say, Java and C#), where all objects in the language must inherit from some global base class, it's entirely possible to have objects that do not descend from NSObject (NSProxy being one example). It's not something you'd do often, but it is possible. The id type means "pointer to any Objective C instance".