Xcode: getting badge value to add it to a label - xcode

I have an app that receives push notification.
I would like to add the badge with the right value near a button inside the application menu (do you remember the old Facebook app?).
I'm trying to get the badge value from the notification in the AppDelegate, save it in NSUserDefault to use it in other view controllers.
NSString * badgeValue = [[userInfo valueForKey:#"aps"] valueForKey:#"badge"];
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:badgeValue forKey:#"badge"];
[defaults synchronize];
The problem is that if I try to put the value in a label the app crashes
'NSInvalidArgumentException', reason: '-[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance
Xcode makes me save badgeValue in a string but when I put the string in the label it says is not a proper string
if ([badgeValue isKindOfClass:[NSString class]]) {
NSLog(#"it is string !!!!!!!!!!!!!!!");
// treat it as a string object
} else {
NSLog(#"it is not a string !!!!!!!!!!!!!!!");
// treat it as a number object
}
By debugging I see that badgeValue is not a real string but __NSCFNumber and if I try to convert it in a string the return value is a long strange number.
I searched everywhere for a way to get the badge value of the notification but the only option I can think of is a php query...Any idea?

What do you mean by "Xcode makes me save badgeValue in a string"? Do you get an error or a compiler warning if you try to type badgeValue as an NSNumber? The documentation and your own logging tell you that the value of the key "badge" is an NSNumber.
NSNumber * badgeValue = [[userInfo valueForKey:#"aps"] valueForKey:#"badge"];
[label1 setIntValue:badgeNumber.intValue];
Does something like this not work?

Yes, Just yesterday I tried with
NSString *string = [NSString stringWithFormat:#"%d", [badgeValue intValue]];
And it works! Thanks for help

Related

What API is there for selecting iTunes library location?

How does one programatically set the iTunes library location on macOS to custom locations using e.g. C / Obj-C or Swift API?
Alternatively, environmental settings, such as modifying plists, using the defaults CLI tool, or similar approaches, are also OK for me.
Ordinarily, selecting a custom iTunes library location is done by launching iTunes while holding down the option key. I need to be able to do this in e.g. a unit testing environment / programatically.
You may be able to set it via the prefs.
This is how I access it.
-(void)loadITunesPrefLibraryPath {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *userPref = [userDefaults persistentDomainForName:#"com.apple.iTunes"];
id dataBaseLoc = [userPref objectForKey:#"Database Location"];
NSLog(#"%s dataBaseLoc is:%#", __PRETTY_FUNCTION__, dataBaseLoc);
NSLog(#"%s dataBaseLoc class is:%#", __PRETTY_FUNCTION__, [dataBaseLoc class]);
NSData* dataBaseData = (NSData*)dataBaseLoc;
BOOL staleBook = NO;
NSError* bookError = nil;
NSURL* dataBaseURL = [NSURL URLByResolvingBookmarkData:dataBaseData options:NSURLBookmarkResolutionWithoutMounting relativeToURL:nil bookmarkDataIsStale:&staleBook error:&bookError];
self.libExtDBfile = dataBaseURL;
}
Once you get the userPrefs for iTunes.
And create a BookMarkData from URL.
You might be able to set it via
[userPref setObject:newDataBaseLoc forKey:#"Database Location"];
also see next answer for possible ITLibrary framework private API access

Compare UITextField with PFQuery of parse.com

I have a small problem .. I hope you can help me ...
In my app I'm using Parse.com for data management.
I have a ViewController that contains a TextField called "Email".
With a query parse.com call all the registered user app and their email. Now I would like to try to compare the values of the textField and those of the query .. Let me give an example ..
The user enters their email in the textField but if this email is already present in the archive of the users (of course taken by the query parse.com) shows an alert that warns him that the Supplied in textField is already existing in parse.com.
I tried to do this but it does not always recognize the email in query..dove am I doing wrong?
P.S. the textField is not in viewController Main but is in another
ViewController called generalData.
-(void)query {
PFQuery *totalUser = [PFUser query];
[totalUser findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
for (PFObject *object in objects) {
[array addObject:object];
NSLog(#"%#", [object objectForKey:NPUserKey_EMAIL]);
// NSStrings
email = generalData.emailTextField.text;
compareEmail = [object objectForKey:NPUserKey_EMAIL];
}
}
}];
}
- (IBAction)presentNextViewController:(id)sender {
if ([generalData.emailTextField.text isEqualToString:compareEmail]) {
NSString *stringError = [NSString stringWithFormat:#"L'email %# è gia presente nei nostri archivi.",email];
NPUMessageView *alertMessage;
alertMessage= [[NPUMessageView alloc] showViewWithMessage:stringError withBackgroundColor:SECONDARY_COLOR];
[self.view addSubview:alertMessage];
[alertMessage showAnimatedView];
NSLog(#"email found in archive");
}
else {
NSInteger index = [controllersContainer indexOfObject:self.destinationViewController];
index = MIN(index+1, [controllersContainer count]-1);
[self presentCurrentViewController:self.currentViewController withPage:index];
}
}
I think you are getting ahead of yourself a little bit. Parse automatically checks for duplicate emails when you try to sign up a new user. Let the user enter their email into the field, and when they try to create the account, display the error Parse returns from the signup method, and let them try again!
https://www.parse.com/docs/ios_guide#users-signup/iOS

How to convert NSData deviceToken to JSON-compatible string to remote API

I need to use the PushWoosh RemoteAPI to register my device.
What is the recommended way to send the deviceIDToken as JSON to the service?
The DeviceID is a NSDATA, but to send it to the remote API I need to convert it to a string.
Which encoding should I use?
NSString *tokenString = [[NSString alloc] initWithData:deviceToken encoding:NSASCIIStringEncoding];
Leads to strange data and is not accepted as a deviceToken.?
My app use this method below, I don't think it is a perfect way for it but it works
NSString *strToken = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]] ;
You can try this one for Remote API register, it might help :)
{
"request":{
"application":"APPLICATION_CODE",
"push_token":"DEVICE_PUSH_TOKEN",
"language":"en", // optional
"hwid": "hardware device id",
"timezone": 3600, // offset in seconds
"device_type":1
}
}

Local Notification When App is Downloaded

I want to have a local notification show up as soon as the application is downloaded off the app store and is opened. Thanks.
You can do that in your app delegate's didFinishLaunchingWithOptions. You need to do the following in this method:
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
....
//Get the version number of the application using this technique: http://stackoverflow.com/questions/458632/how-can-my-iphone-app-detect-its-own-version-number
NSString version = [self appVersion];
//Because you only want to display the notification on first launch so have a flag in user defaults to track that. Also note that you need to include this in your registerDefaults and set to NO
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL alreadyDisplayedNotification = [defaults boolForKey:#"alreadyDisplayedNotificationOnStartForVersion"];
if ([version isEqualToString:#"VersionForWhichYouWantNotification"] && !alreadyDisplayedNotification) {
//Display Notification...
// Set the flag in user default to track that notification has been displayed
[defaults setBool:YES forKey:#"alreadyDisplayedNotificationOnStartForVersion"];
}
.....
}

NSManagedObjectID into NSData

I found this wonderful NSManagedObjectID. This would be very good for referencing an Entity/NSManagedObject/NSEntityDescription, right?
Let's get an ID from an entity:
NSEntityDescription *entity = [self newEntity];
NSManagedObjectID *objID = [entity objectID];
So... any idea how to get this objID into a string? Or better: NSData. Actually something to be able to save it to the NSUserDefaults. ;-)
Btw: NSFetchRequest doesn't want to work in my case. I use an modified version of this example: answer of an old question.
To get an archived URI corresponding to a NSManagedObject's objectID:
NSManagedObject* myMO;
...
NSURL *uri = [[myMO objectID] URIRepresentation];
NSData *uriData = [NSKeyedArchiver archivedDataWithRootObject:uri];
In order to get back to an instance of the original managed object, you need a CoreData stack with the persistent store holding that instance already added to the NSPersistentStoreCoordinator. Then:
NSData *uriData;
NSPersistentStoreCoordinator *psc;
NSManagedObjectContext *moc; //with moc.persistentStoreCoordinator = psc.
...
NSURL *uri = [NSKeyedUnarchiver unarchiveObjectWithData:uriData];
NSManagedObjectID *moID = [psc managedObjectIDForURIRepresentation:uri];
NSManagedObject *myMO = [moc objectWithID:moID];
From the NSManagedObjectID documentation:
Object IDs can be transformed into a
URI representation which can be
archived and recreated later to refer
back to a given object (using
managedObjectIDForURIRepresentation:
(NSPersistentStoreCoordinator) and
objectWithID:
(NSManagedObjectContext). For example,
the last selected group in an
application could be stored in the
user defaults through the group
object’s ID. You can also use object
ID URI representations to store “weak”
relationships across persistent stores
(where no hard join is possible).
Just turn it into a URL then turn that into a string or a data.
Did you look at URIRepresentation? It's easy to convert an NSURL to an NSString, and that to an NSData.
You don't need to convert the NSURL into an NSString before archiving. Just archive the NSURL.
Edit: I've recently learned that an object's ID can change, such as after a migration. It therefore seems like not a good idea to save an ID to disk expecting to be able to reference the object later.
Here's the cleanest and shortest way I've found to do this currently, using the setURL and getURL methods added in 4.0 to avoid extra calls to NSKeyedUnarchiver and NSKeyedArchiver:
Setter:
+ (void)storeSomeObjectId:(NSManagedObjectID *)objectId
{
[[NSUserDefaults standardUserDefaults] setURL:[objectId URIRepresentation]
forKey:#"someObjectIdKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Getter:
+ (SomeManagedObject *)getObjectByStoredId
{
NSURL *uri = [[NSUserDefaults standardUserDefaults] URLForKey:#"someObjectIdKey"];
NSManagedObjectID *objectId = [self.persistentStoreCoordinator managedObjectIDForURIRepresentation:uri];
SomeManagedObject *object = [self.managedObjectContext objectWithID:objectId];
}
As #preston said, don't save an objectID to disk, instead:
Make a new attribute on your entity called "id"
Make a new attribute on your entitys parent entity called "myEntitysMaxId"
Override your entitys parent implementation "addNewMyEntityObject:"
There, increase "myEntitysMaxId" and set that value as the new entitys "id"
Do as you normally do when you fetch an entity based on its attributes!
Much cleaner and better!

Resources