Terminating app due to uncaught exception 'NSInvalidArgumentException' 5 - objective-c

i am getting this error while running my app:
my code is:
- (IBAction)yes:(id)sender {
UIAlertView *msgbox=[[UIAlertView alloc]initWithTitle:#"Warrning" message:nil delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
if ([_usernametextbox.text length]>0)
{
if ([_passwordtextfield.text length]>0)
{
NSMutableString *ms=[[NSMutableString alloc]initWithFormat:url,_usernametextbox.text,_passwordtextfield];
NSURL *serviceurl=[[NSURL alloc] initWithString:ms];
NSError *error=nil;
NSData *data=[NSData dataWithContentsOfURL:serviceurl options:NSDataReadingUncached error:&error];
NSMutableDictionary *dic=[[NSMutableDictionary alloc]init];
NSString *jsondata=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
SBJSON *parsedata=[[SBJSON alloc] init];
dic=[parsedata objectWithString:jsondata error:nil];
if([dic count]>0)
{
NSMutableString *st=[[NSMutableString alloc]initWithString:[dic objectForKey:#"loginResult:#""+"]]; //#" " withString:#"+"
if ([st isEqualToString:#"YES"])
{
UIAlertView * alert=[[UIAlertView alloc] initWithTitle:#"accept" message:#"correct username" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
else
{
UIAlertView * alert=[[UIAlertView alloc] initWithTitle:#"Error" message:#"Invalid UserName and Password" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
}
else
{
msgbox.message=#"Please Enter Password...";
[msgbox show];
}
}
else
{
msgbox.message=#"Please Enter Username...";
[msgbox show];
}
I get the error:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '* -[NSConcreteData
initWithContentsOfURL:options:error:]: nil URL argument'
on the line:
NSMutableString *st=[[NSMutableString alloc]initWithString:[dic objectForKey:#"loginResult:#""+"]]; //#" " withString:#"+" if ([st isEqualToString:#"YES"])

Related

FBSession.session.accessTokenData.userID always nil

Been using FBConnect for selecting friends, but the FBSession's accessTokenData never has the userID of the user that started the session (also isn't present in their login demo). FBFriendPickerViewController returns friend users with their Ids just fine, but I don't see anything about the current user. Is it possible to get the current user's Id from the FB active session, accessTokenData, or some other means?
EDIT:
Is it possible to get the user's Id returned from this call?
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile", #"user_friends"]
It'll be much nicer to do it all in one step.
You have to request to "/me" to get an 'user_id' since access_token property is encrypted and you couldn't access it from that way.
Here's what I ended up doing:
if (!FBSession.activeSession.isOpen) {
// if the session is closed, then we open it here, and establish a handler for state changes
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile", #"user_friends"]
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
else if (session.isOpen) {
if ([session.declinedPermissions containsObject:#"user_friends"]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"friends"
message:#"Must allow accessing friends"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
else {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
else {
NSLog(#"name %# id %#", user.first_name, user.objectID);
[[FBRequest requestForMyFriends] startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary* result,
NSError *error) {
NSArray* friends = [result objectForKey:#"data"];
NSLog(#"Found: %i friends", friends.count);
for (NSDictionary<FBGraphUser>* friend in friends) {
NSLog(#"I have a friend named %# with id %#", friend.name, friend.objectID);
}
}];
}
}];
}
}
}];

Migrating iCloud store to local

Migration works fine on Simulator. However on a device, I see no error messages but migrated store is empty.
NSDictionary *iCloudOptions = #{
NSPersistentStoreUbiquitousContentNameKey : #"iCloudNimbleStore",
NSPersistentStoreUbiquitousContentURLKey : #"transactions_logs",
NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES
};
NSDictionary *localOptions = #{NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES
};
if (![[NSFileManager defaultManager]fileExistsAtPath:self.storeURL.path]) {
#synchronized(#"Migration")
{
// thread-safe code
if ([[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]) {
NSLog(#"iCloud");
[self migrateStoreFromURL:[self nb_URLToStoreWithFilename:[self nb_appName]]options:iCloudOptions];
}else{
[self migrateStoreFromURL:[self nb_URLToStoreWithFilename:[NSString stringWithFormat:#"%#.sqlite", [self nb_appName]]] options:localOptions];
//
[self migrateStoreFromURL:[self nb_URLToOldStoreWithFilename] options:localOptions];
}
}
}
NSDictionary *options = #{
NSMigratePersistentStoresAutomaticallyOption:#YES
,NSInferMappingModelAutomaticallyOption:#YES
};
NSError *error = nil;
[_coordinator lock];
_store = [_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeURL] options:options error:&error];
[_coordinator unlock];
if (!_store) {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Loading Fail" message:[NSString stringWithFormat:#"Failed to add store. Error: %#", error] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
NSLog(#"Failed to add store. Error: %#", error);abort();
} else {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Loading Success" message:[NSString stringWithFormat:#"Successfully added store: %#", _store] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
NSLog(#"Successfully added store: %#", _store);
if (_store && !error) {
// Encrypt the password database
NSError *encrError;
NSDictionary *fileAttributes = [NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey];
if (![[NSFileManager defaultManager] setAttributes:fileAttributes ofItemAtPath:self.storeURL.path error:&encrError]){
NSLog(#"Unresolved error with password store encryption %#, %#", encrError, [encrError userInfo]);
abort();
}else {NSLog(#"Encrypted");}
}
}
Here is migration procedure:
- (void)migrateStoreFromURL:(NSURL *)oldStoreURL options:(NSDictionary *)oldOptions{
if (debug==1) {
TFLog(#"Running %# '%#'", self.class, NSStringFromSelector(_cmd));
}
if (_store)
{
NSLog(#"NOT NEEDED");
return;
}
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Migration" message:[NSString stringWithFormat:#"Found old store at %#",oldStoreURL.path] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:self.storeURL.path]) {
NSDictionary *options =
#{
NSMigratePersistentStoresAutomaticallyOption:#YES
,NSInferMappingModelAutomaticallyOption:#YES
};
NSError *error = nil;
[_coordinator lock];
NSPersistentStore *srcPS = [_coordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:oldStoreURL
options:oldOptions
error:&error];
_store = [_coordinator migratePersistentStore:srcPS
toURL:self.storeURL
options:options
withType:NSSQLiteStoreType
error:&error];
[_coordinator unlock];
if (_store && !error) {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Migration Success" message:[NSString stringWithFormat:#"Old store successfully migrated from %#",oldStoreURL.path] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
// Encrypt the password database
NSError *encrError;
NSDictionary *fileAttributes = [NSDictionary dictionaryWithObject:NSFileProtectionComplete forKey:NSFileProtectionKey];
if (![[NSFileManager defaultManager] setAttributes:fileAttributes ofItemAtPath:self.storeURL.path error:&encrError]){
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Encryption Error" message:[NSString stringWithFormat:#"Unresolved error with password store encryption %#, %#", encrError, [encrError userInfo]] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
}else{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Migration Error" message:error.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
}
Upd.: I checked size of the newly migrated store and it's 0. Most strange is that _store && !error is true. I also tried to add NSPersistentStoreRemoveUbiquitousMetadataOption: #YES to migration options but it doesn't change anything.
Upd. 2 I think that on a device iCloud store url is nil before its loaded. I need some workaround to wait until its finished.
I'm not 100% sure I understand what you are trying to do with the migrations. It is common to seed data in an empty store with a migration, but it looks like you are trying to migrate data out of iCloud into your local store. Is that right? You should not need to do that. iCloud should automatically add the data from other devices to your store.
This line also doesn't look right:
NSPersistentStoreUbiquitousContentURLKey : #"transactions_logs",
I think you want to use a URL there that points to the transaction log directory inside the iCloud container. Eg.
NSURL *containerURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
NSURL *url = [containerURL URLByAppendingPathComponent:#"transactions_logs"];
When working with iCloud, it is important to realize that data does not transfer instantaneously. It can take a while to arrive, and your app doesn't really have any way to know for sure if there is data coming. You can monitor metadata with metadata queries, but even that often arrives some time after data on other devices has already been generated.
So simply looking in the ubiquity container for data will not help much, because there may or may not be data available. You just do not know, and you have to develop your approach with that assumption in mind, so that it can handle any delays.
The migrations required to get iCloud sync working with Core Data are messy and unnecessary. You are probably much more likely to get things working well with a framework that does that stuff automatically, such as Core Data Ensembles. (Disclosure: I am the developer of Ensembles.)

Objective-C compiler error

Need help with the [currentValue, targetValue, difference]; line. It says that initializer element is not a compile-time element. Please post solution.
NSString *message = [NSString stringWithFormat:
#"The value of the slider is: %d\nThe target value is: %d\nThe difference is: %d",
[currentValue, targetValue, difference];
UIAlertView *alertView = [[UIAlertView alloc]]
initWithTitle:#"Hello, World!"
message:message
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
Should be:
NSString *message = [NSString stringWithFormat: #"The value of the slider is: %d\nThe target value is: %d\nThedifference is: %d", currentValue, targetValue, difference];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Hello, World!"
message:message
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
You have an extra '[' before current and and extra ']' after the UIAlertView alloc.

Why does isEqualToString not work for NSString?

I am trying to code the login process for an iPhone app in XCode. The problem is with the NSString serverOutput below. When I print it using printf(serverOutput.UTF8String); it prints 'Yes' to the console. However when I compare serverOutput to "Yes" it doesn't work. Any help would be appreciated. Here's my code:
- (IBAction) loginButton: (id) sender
{
// TODO: spawn a login thread
indicator.hidden = FALSE;
[indicator startAnimating];
NSString *post =[NSString stringWithFormat:#"username=%#&password=%#",userName.text, password.text];
NSString *hostStr = #"http://10.243.1.184/connectDB.php?";
hostStr = [hostStr stringByAppendingString:post];
NSData *dataURL = [NSData dataWithContentsOfURL: [ NSURL URLWithString: hostStr ]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
printf(serverOutput.UTF8String);
if([serverOutput isEqualToString:#"Yes"]){
UIAlertView *alertsuccess = [[UIAlertView alloc] initWithTitle:#"Congrats" message:#"You are authorized"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertsuccess show];
[alertsuccess release];
}
else {
UIAlertView *alertsuccess = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Username or Password Incorrect"
delegate:self cancelButtonTitle:#"OK"otherButtonTitles:nil, nil];
[alertsuccess show];
[alertsuccess release];
//[self.navigationController pushViewController:DashboardViewController animated:YES];
loginbutton.enabled = TRUE;
}
loginbutton.enabled = FALSE;
}
Based on helping others with similar situations I would say the problem is that the response from the server isn't just the string "Yes". Most likely there is some whitespace before and/or after the text. Perhaps a stray newline or two.
Try this:
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
NSLog(#"Result = '%#'", serverOutput); // look for space between quotes
serverOutput = [serverOutput stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

UIAlertView with timestamp

I am a newbie to Objective-C. I would like to display the current date and time in an alert view.
- (IBAction)postButtonPressed:(UIButton *)sender {
NSString *formatString = [NSDateFormatter dateFormatFromTemplate:#"MMM d, yyyy h:mm" options:0 locale:[NSLocale currentLocale]];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:formatString];
NSString *todayString = [dateFormatter stringFromDate:[NSDate date]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message Posted" message:#"Your Message is posted on: #todayString" delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
}
Your alert message string needs to be redone. Try this:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message Posted"
message:[NSString stringWithFormat:#"Your Message is posted on: %#", todayString]
delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
You can concate NSString using stringWithFormat: or stringWithString: there's also other appeding functions available, see doc
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message Posted" message:[NSString stringWithFormat:#"Your Message is posted on: %#",todayString] delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
[alert release]; //don't forget to release UIAlertView object if you don't using ARC
Try
NSString *str = [NSString stringWithFormat:#"Your Message is posted on: %#", todayString];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message Posted" message:str delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];