CFData vs CFString - cocoa

I have a CFMutableDictionaryRef, part of which in debugger is:
"device-id" = <72270000>;
model = <474d4120 39353000>;
"vendor-id" = <86800000>;
Now I can get value of the key model using CFDataRef which returns string like "GMA 950", as compared to the value above.
But I cannot get value of "vendor-id"using same method so I try with CFString, which returns <86800000> instead of a string. So how to retreive correct value of the vendor id (which I already know should return 0x8086 for Intel) ??

found it:
have to format the string retreived with CFString as:
NSString *id = [NSString stringWithFormat:#"0x%X",*((UInt32*)CFDataGetBytePtr(cfstr))];

Related

NSURL errors with caret ^ in string

Attempting to get data on the S&P500 (symbol: ^GSPC) from Yahoo Finance. In playgrounds and scripts, the presence of a caret (^) in the string passed to NSURL errors with "Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, sub code=0x0)". Xcode 6b6 and b7.
Works fine with other ticker symbols (AAPL, MSFT, etc).
Any suggestions for how to get this working?
let symbols:String = "^GSPC"
let financeURL:String = "http://finance.yahoo.com/d/quotes.csv?s=\(symbols)&f=sl1c6p2"
var financeNSURL: NSURL = NSURL(string: financeURL) // ERROR (see above)
let tickerNSData: NSData = NSData(contentsOfURL: financeNSURL)
var output:NSString = NSString(data:tickerNSData, encoding:NSUTF8StringEncoding)
It's crashing because Swift (at least in Xcode6-Beta7) doesn't support returning nil from an object initializer. From the release notes:
Swift does not support object initializers that fail by returning
null. (16480364)
Workaround: If there is a factory method, use it instead. Otherwise,
capture the result in an optional. For example:
let url: NSURL? = NSURL(string: "not a url")
So, to avoid a crash, declare your financeNSURL as NSURL? (as in the example from the docs above), or use NSURL.URLWithString() instead of init(string:).
However, the root of the problem is that you're not encoding your URL parameters correctly.
If you call stringByAddingPercentEncodingWithAllowedCharacters(...) on symbols it works:
let symbols:String = "^GSPC".stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
let financeURL:String = "http://finance.yahoo.com/d/quotes.csv?s=\(symbols)&f=sl1c6p2"
let financeNSURL: NSURL? = NSURL(string: financeURL)
if let url = financeNSURL {
let tickerNSData: NSData = NSData(contentsOfURL: url)
var output:NSString = NSString(data:tickerNSData, encoding:NSUTF8StringEncoding)
}
Output:
"^GSPC",1999.83,"-2.45","-0.12%"
When creating a NSURLwith init method NSURLWithString: the parameter URLString must be a properly encoded URL string. Your's is not. So, what is this a "properly encoded URL string"?
The corresponding official documentation gives a few more hints where to read:
"URLString: The URL string with which to initialize the NSURL object. This URL string must conform to URL format as described in RFC 2396, and must not be nil. This method parses URLString according to RFCs 1738 and 1808."
(links are mine).
So basically, you need to separately encode each URL component from your source string component using the correct variant of the percent encoding algorithm. Then, compose all encoded string components to the final URL string.
This can be tedious and is certainly error prone. Thus, since iOS 8 there is NSURLComponents (see docs here) which can aid you in this task.

iPhone SDK: Append NSString and Count Data

The web service that I am accessing returns this values:
A1;A2;A3;A4;A5;B2;B10;B11;B12;
I want to get the total count of all the data returned separated by ;. How can I do this? I'm thinking of doing a loop inside the string, get the value before ; but getting confused on how to properly run the loop.
There are many string functions and you can use one of them, that is componentsSeparatedByString.
Considering that above mentioned return value is a NSString.
NSString *strResponse = #"A1;A2;A3;A4;A5;B2;B10;B11;B12;";
NSArray *arCount = [strResponse componentsSeparatedByString:#";"];
NSLog(#"Total objects in response is: %d", [arCount count]);

Setting to-one relationship value in Core data get unrecognized selector sent to instance error

I have 2 entities(A, B) in my model.
They have such reverse to-one relationship: A<---->B.
Here is how I add new record into core data:
NSManagedObject *moA = NSEntityDescription insertNewObjectForEntityForName:#"A"
inManagedObjectContext:managedObjectContext];
NSManagedObject *moB = NSEntityDescription insertNewObjectForEntityForName:#"B"
inManagedObjectContext:managedObjectContext];
[moA setValue:#"http://www.apple.com" forKey:#"url"];
[moB setValue:#"Apple inc." forKey:#"title"];
// set reverse relationship
[moA setValue:moB forKey:'relationToB'];
[moB setValue:moA forKey:'relationToA'];
After I run this code, I get error:
unrecognized selector sent to instance
This line:
[moA setValue:moB forKey:'relationToB'];
... should be:
[moA setValue:moB forKey:#"relationToB"];
In the original, you are attempting to pass a C string literal as the key instead of an NSString object. In key-value coding, the name of the key is converted into a method name (a selector) e.g. #"relationToB" gets converted to a selector of setRelationToB:
However, the C string literal is not an object but just an address for a memory range which converts into a gibberish selector name producing the error.

generating an objectForKey from an array

I'm having success when I use this code to get a string from an array of file names called "fileList":
cell.timeBeganLabel.text = [[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension];
so I expected the same code to generate the same string as a key for me in this:
NSDictionary *stats = [thisRecordingsStats objectForKey:[[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension]];
cell.durationLabel.text = [stats objectForKey:#"duration"];
or this:
NSDictionary *stats = [thisRecordingsStats objectForKey:#"%#",[[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension]];
Both build without error, and the log shows my data is there: but I'm getting a blank UILabel.
Have I not written the dynamic key generator correctly?
I'm having success when I use this code to get a string from an array of file names called "fileList":
cell.timeBeganLabel.text = [[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension];
So, the result of that message expression is your key, right?
That is to say, the keys in your dictionary are filenames without extensions?
so I expected the same code to generate the same string as a key for me in this:
NSDictionary *stats = [thisRecordingsStats objectForKey:[[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension]];
cell.durationLabel.text = [stats objectForKey:#"duration"];
You compute the filename without extension as before.
You look up the object for this string in the thisRecordingsStats dictionary, thus obtaining another dictionary, with which you initialize the stats variable.
You look up the object for the “duration” key in the stats dictionary, and set the durationLabel's text to this object.
or this:
NSDictionary *stats = [thisRecordingsStats objectForKey:#"%#",[[[self.fileList objectAtIndex:[indexPath row]] lastPathComponent] stringByDeletingPathExtension]];
Adding the #"%#", part doesn't make sense, since objectForKey: doesn't take a format string. Compare the documentation for NSString's stringWithFormat: method to the documentation for NSDictionary's objectForKey: method.
The code “works” because what you have passed as the argument to objectForKey: is a comma expression. C's comma operator evaluates both sides and evaluates to the right-hand side. However, in this case as in most others, it adds nothing. For reasons like this, the comma operator is rarely used and even more rarely used on purpose.
Cut the #"%#", part out.
Back to the problem:
Both build without error, and the log shows my data is there: but I'm getting a blank UILabel.
Well, you say the key you're generating from the string in your fileList array shows up in the UILabel, so the problem is one of these:
thisRecordingStats is nil.
thisRecordingStats does not contain an object for the key you generated from the string in self.fileList.
thisRecordingStats does contain an object for the key you generated from the string in self.fileList, and it is a dictionary, but it does not contain a value for the key “duration”.
thisRecordingStats does contain an object for the key you generated from the string in self.fileList, and it is a dictionary, and it contains a value for the key “duration”, but that value is an empty (zero-length) string.
You should also check the Debugger Console for messages that suggest other problems. For example, a “does not respond to selector” message may be because thisRecordingStats contains an object for the key you generated from the string in self.fileList, but it is not a dictionary.
Finally, I suggest constructing one or more model object classes instead of nesting dictionaries like this. It tends to make the code much easier to read and to debug. In particular, the dictionaries that ostensibly have objects for the key “duration” should be model objects.

NSPredicate and arrays

I've got a short question. I have an NSArray filled with Cars (which inherits from NSObject). Car has the #property NSString *engine (also regarded #synthesize)
Now I want to filter the array using NSPredicate:
predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"(engine like %#)", searchText]];
newArray = [ArrayWithCars filteredArrayUsingPredicate:predicate];
This throws an valueForUndefinedKey error. Is the predicateWithFormat correct?
Thanks for your responses.
Here's the real reason why it's not working:
When you build a string using stringWithFormat:, it's going to come up looking like this:
#"engine like searchText"
You then pass it to predicateWithFormat:, which is going to see that both the lefthand side and the righthand side of the comparison are unquoted strings, which means it's going to interpret them as if they were keypaths.
When this code runs, it's going to be doing:
id leftValue = [object valueForKey:#"engine"];
id rightValue = [object valueForKey:#"searchText"];
return (leftValue is like rightValue);
The exception getting thrown is your object complaining that it doesn't have a method named "searchText", which is correct.
Contrast this to if you took out the stringWithFormat: call and just put everything directly into predicateWithFormat::
NSPredicate *p = [NSPredicate predicateWithFormat:#"engine like %#", searchText];
predicateWithFormat: is smart. It sees "aha, a %# replacement pattern! this means I can pop an argument off the argument list and box it up and use it as-is". That's exactly what it's going to do. It's going to pop the value of searchText off the argument list, box it in an NSExpression, and insert it directly into the parsed expression tree.
What's most interesting here is that the expression it creates will be a constant value expression. This means it's a literal value; not a key path, not a collection, etc. It will be the literal string. Then when your predicate runs, it's going to do:
id leftValue = [object valueForKey:#"engine"];
id rightValue = [rightExpression constantValue];
return (leftValue is like rightValue);
And that is correct, and is also why you should not pass stuff through stringWithFormat: before passing it to predicateWithFormat:.
k, I found the mistake.
predicate = [NSPredicate predicateWithFormat:#"engine like *%#*", searchText];
works correct. The ** were missing. Additionally your searchText should be uppercase.
#Josuhua
this is no real code, just to visualize my problem
First, your code is more verbose than necessary, which always opens you up to the possibility that it's wrong. Try:
predicate = [NSPredicate predicateWithFormat:#"engine like %#", searchText];
Second, "ArrayWithCars" looks like a class name (by convention, classes begin with upper-case). Is it actually a class or an improperly-named local variable (ex: "arrayWithCars" or just "cars")?
Third, what is the exact error? What key is undefined? Don't paraphrase errors when asking others for help - we can't see what you're seeing unless you show us.
Try with this link.You may know different ways of using NSPredicate

Resources