I am using Parse.com as a backend server, and am uploading data. I have a PFObject called person which has a column called 'Email' of Boolean type. I have a Core Data object with a BOOL property called email, which is set by: [NSNumber numberWithBool:[self.email isOn]];. When I try to set the PFObject as follows:
Person[#"email"] = [person.email boolValue];,
it gives me an error saying I am assigning a bool to id (Person is a PFObject). Am I doing something wrong?
What is the type of a PFObject's email property?
The fact that you can send it a boolValue message makes me think it might be an NSNumber. (Either that or NSString)
If it's already an NSNumber, you don't have to do anything. Simply assign the person.email directly to your destination key/value pair:
aPerson[#"email"] = person.email;
If person.email is a string, then you could use:
aPerson[#"email"] = #([person.email boolValue]);
Which would convert person.email to a bool, and then create an NSNumber using that bool.
BTW, you should not name variables, properties, or methods starting with an upper case letter. Objective-C has the strong convention that only classnames should start with an upper case letter.
I also cringe at having 2 different variables that only differ based on case ("Person" and "person"). That's a typing mistake away from a future bug.
According to the iOS Documentation, boolValue returns a primitive BOOL. id is not primitive, and can only be assigned objects such as NSNumber.
When using Parse, I normally send NSNumbers up to the server, as you cannot send BOOLs. Try writing this instead.
Person[#"email"] = [NSNumber numberWithBool:self.email];
This will send the NSNumber value up to the server, and when you need to retrieve it in BOOL form, just use NSNumber's boolValue
Related
So, I was wondering if it is possible to save a function to user defaults using Swift. For a string, for example, I would do this:
var inputData = "Hi"
NSUserDefaults.standardUserDefaults.setValueForKey(inputData, forKey: "data")
Then to save it do a variable, I would say:
var gotData = NSUserDefaults.standardUserDefaults.valueForKey("data")!
Now, my question is, if it is possible to save a function to user defaults. For example:
var inputData = func helloWorld(){println("Hello World!")}
Is it possible to then call that function that was saved to user defaults by doing something similar to .valueForKey ?
Any help is valued! Thanks a lot in advance!
You cannot save a function to NSUserDefaults. From the NSUserDefaults Class Reference:
A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData.
A function is not any of the supported types, and as far as I know you cannot archive a function either.
I was reading the apple documentation to learn how to format text for iOS. I came across an attributed string and most of it made sense to me. However, while looking up the different kinds of attributes, I saw that they are all declared as NSString.
For example:
NSString *const NSFontAttributeName;
NSString *const NSParagraphStyleAttributeName;
...
...
We pass in these string objects in a dictionary with the value being that particular attribute (e.g., a UIFont object). However, what I do not understand is what the content of that string has to do with the attribute itself. Do they just contain the name of the attribute? (i.e NSFontAttributeName might contain a string like #"NSFontAttribute")
Surely there must be a reason why has apple to chosen to do it this way?
Edit: My question isn't about why they use a string object as a key to the dictionary but why they use a predefined constant string object named NSFontAttributeName instead of allowing us to manually pass in a string #"NSFontAttribute" as the key. That's why I wondered whether the contents of their predefined string object has anything to do with this.
In this case, Apple uses an NSDictionary to contain an arbitrary set of key/value pairs. Doing it this way means you have a lot of flexibility because you can have no attributes, one attribute, or two dozen attributes with the same programming interface. And if in two years time there are attributes available that you haven't even thought about, Apple doesn't have to introduce any new APIs to support you setting these attributes.
The reason for using a constant instead of a string literal is that the compiler can save you if you misspell a name. If you wrote #"NSFontattribute" instead of #"NSFontAttribute", the compiler wouldn't know that you got it wrong.
As the attributes are expressed in an NSDictionary and you can only hold Objective-C objects in Objective-C collection classes, you have to use an object of some sort. They could have used enumerated integer values, wrapped in NSNumber objects, instead:
typedef enum {
KEYONE,
KEYTWO
} KeyValues;
NSDictionary *attributes = [NSDictionary dictionary];
attributes[#(KEYONE)] = #"The attribute";
One advantage of using an NSString as a key is that it's easier to debug at the slight expense of generating the dictionary key hash from the string (which must be very slightly more expensive than generating it from an NSNumber object).
When creating an SKStoreProductViewController, I pass a dictionary with a parameter for the store identifier. :
#{ SKStoreProductParameterITunesItemIdentifier : #010101010 };
This value is supposed to be an NSNumber (as it is above):
The value associated with this key is an instance of NSNumber, representing the iTunes identifier for the item you want the store to display when the view controller is presented.
But it works without complaint when I pass the value as a string:
#{ SKStoreProductParameterITunesItemIdentifier : #"010101010" };
What's going on here? Is NSNumber automatically creating the correct number type from the string that it's given? Is this occurring in the NSNumber or is StoreKit doing this?
Actually, thinking about it...
Initially I thought they must be converting the NSString into an NSNumber before doing whatever they need to do to get the information you are looking for.
However, on second thought...
I would guess that StoreKit is using the value against SKStoreProductParameterITunesItemIdentifier in a string. In which case they would do something like...
NSString *someStringToGetTheResults = [NSString stringWithFormat:#"thisIsThePath...?storeKitID=%#", dictionary[SKStoreProductParameterITunesItemIdentifier]];
This will be the same whether you pass in #12345 or #"12345".
Possibly...
No real way to tell though.
The docs say that the value stored in the SKStoreProductParameterITunesItemIdentifier key is supposed to be an NSNumber. Saving anything else in that key may work today, but may also stop working after any OS release, so don't do it.
As others have suggested, it's pretty likely that the store kit is fetching the value of the SKStoreProductParameterITunesItemIdentifier key, assuming it's an NSNumber, and sending it an integerValue method to get it's numeric value. You got lucky since NSNumber and NSString both have an integerValue method.
Specifically, say I have an NSManagedObject with a "statusCode" attribute set to transformable, and a reversible value transformer subclass to covert from NSStrings to NSNumbers and vice versa. The idea is to use the value transformer so that I receive JSON and a string from a "status" key in the JSON automatically maps to an NSNumber that represents that status code in an NSManagedObject. Conversely if I were to upload the NSManagedObject to a server, at that point its status attribute would be transformed from an NSNumber to a string for the JSON.
So far so good. But, what if I also want to be able to get a simple int out of the NSManagedObjec's status property, so that I can AND it with enums in code?
That is, I'd lie to cover 3 cases:
myManagedObject.status = [JSONResponse valueForKey:#"status"] (should use transformer to do NSString -> NSNumber)
[JSONforUpload setValue:myManagedObject.status forKey:#"status"] (should use transformer to do NSNumber->NSString)
From elsewhere in code, anything along the lines of: if(myManagedObject.status & statusInProgress) ... where statusInProgress is an enum.
I'm thinking I could temporarily disable the value transformer, however I have no idea if the NSManagedObject has a reference to it, or if I should disable it from the NSValueTransformer class, which apparently keeps a table of registered transformers?
I know that for the 3rd case I could just do [myManagedObject.status intValue] and then do the bitwise comparison, but I'm wondering if there's any way I can have the intValue] be returned automagically, from the user of this object's point of view.
Any ideas?
Why don't you just write two additional methods for the JSON transform and leave the property as integer? Then you'd have the best from both worlds.
One approach would be to add a property to the transformer so that it switches between string and enum reversed values. That would work, though I ended up doing a enum<->string transformer and not using it over a transformable attribute (instead I left the managed object's attribute as int) but rather instantiating it only for the JSON <-> object conversion. After that, throughout code I just use the int attribute as is.
Assuming that this entity has its own distinct managed object subclass, you could also simply add another pair of accessor methods to the class to encapsulate the conversion between NSNumber and int values. (Or add a transient attribute, if it needs to be part of the model. But you'd still need to write custom accessors to synch up the values.)
I'm trying to create an NSDictionary that keeps track of calling objects for a function. I'd like to create a unique string for each object without knowing anything about it. My first thought is to use the memory address of the object's pointer, but I'm not sure how to do that.
Any thoughts? I need to use some sort of unique id from an NSObject as the keys in my dictionary.
If your application supports iOS6 only check the NSDictionaryOfVariableBindings macro.
The code would be something like :
// Create the dictionary
NSObject *firstObject = [NSString stringWithString:#"My first item"];
NSObject *secondObject = #"[#"an", #"array", #"of", #"strings"]";
NSDictionary *theDic = NSDictionaryOfVariableBindings(firstObject, secondObject);
// Access data
NSString *singleString = [theDic objectForKey:#"firstObject"];
NSArray *listOfStrings = [theDic objectForKey:#"secondObject"];
My suggestion is not to use a dictionary. If you were to place them into an array, you could think of it as a dictionary with automatically generated unique keys (the indexes). It's really exactly what you are describing. If for some reason you have to use a dictionary, my suggestion is to implement that same model I'm speaking of, but you would have to generate and maintain the keys.
While I agree that your solution sounds like it may not be the best approach, have you considered -hash in the NSObject protocol? All NSObjects should return one. Be forewarned that it's a hash, so there's a chance that two different objects could have the same hash.
You could also consider a category on NSObject that your collection implements. The category could generate a UUID to use as a key.