如何创建登录条件和核心数据表值不能存储两次

Posted

技术标签:

【中文标题】如何创建登录条件和核心数据表值不能存储两次【英文标题】:How to create login condition and core data table values can't be stored twice 【发布时间】:2016-09-29 10:47:21 【问题描述】:

我的项目有一些问题。我的移动应用程序的登录表单附加到 php 登录服务并且性能也很好。我还添加了核心数据。在核心数据表中,登录表单的用户名文本字段和密码文本字段及其数据存储在本地数据库中,可以正常工作。

但我想,当用户第一次登录时,值存储在本地数据库值存储中,当用户从这里注销和第二次用户使用相同的登录 ID 和密码登录时,数据库无法记录两次。

显然,我希望值不能存储两次。请建议它是如何工作的。

我的代码

- (IBAction)btn_action:(id)sender 
   if([[self.tx_userid text] isEqualToString:@""] || [[self.tx_password text] isEqualToString:@""] ) 
    
     
   else 
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"MYURL"]];
    
    
    //create the Method "GET" or "POST"
    [request setHTTPMethod:@"POST"];
    
    
    //Pass The String to server(YOU SHOULD GIVE YOUR PARAMETERS INSTEAD OF MY PARAMETERS)
    NSString *userUpdate =[NSString stringWithFormat:@"loginid=%@&loginpassword=%@",_tx_userid.text,_tx_password.text, nil];
    
    
    
    //Check The Value what we passed
    NSLog(@"the data Details is =%@", userUpdate);
    
    //Convert the String to Data
    NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
    
    //Apply the data to the body
    [request setHTTPBody:data1];
    
    //Create the response and Error
    NSError *err;
    NSURLResponse *response;
    
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
    
    //  if ([response statusCode] >= 200 && [response statusCode] < 300)
    
        
        
        NSError *error = nil;
        NSDictionary *jsonData = [NSJSONSerialization
                                  JSONObjectWithData:responseData
                                  options:NSJSONReadingMutableContainers
                                  error:&error];
        
        int success = [jsonData[@"success"] integerValue];
        
        
        if(success == 1)
        
            // stored in local DB
            NSManagedObjectContext *context = [self managedObjectContext];
            
            NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:@"Loginuser" inManagedObjectContext:context];
            
            [newDevice setValue:self.tx_userid.text forKey:@"userid"];
            [newDevice setValue:self.tx_password.text forKey:@"password"];
            
            NSError *error = nil;
            // Save the object to persistent store
            if (![context save:&error]) 
                NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
            

            NSLog(@"Login SUCCESS");
            [self performSegueWithIdentifier:@"login_success" sender:self];
         else 
            
            NSString *error_msg = (NSString *) jsonData[@"error_message"];
            [self alertStatus:error_msg :@"Sign in Failed!" :0];
        
        
    
    





NSLog(@"app dir: %@",[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]);


  

 - (void) alertStatus:(NSString *)msg :(NSString *)title :(int) tag

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
                                                    message:msg
                                                   delegate:self
                                          cancelButtonTitle:@"Ok"
                                          otherButtonTitles:nil, nil];
alertView.tag = tag;
[alertView show];
 

【问题讨论】:

你的意思是说如果用户登录一次然后相关数据保存到数据库然后他在注销后再次登录,那个时候你不想在数据库中输入相同的用户数据? @vaibhav 是的,你是对的。但是该怎么做呢? 看看我的ans如果适合.. 【参考方案1】:

首先您检查登录ID与用户登录时所有存储的登录ID不同。 如果相同则用户允许登录而不存储数据,否则首先存储数据并允许登录。

【讨论】:

请解释一些代码。因为我尝试了很多次,但都不能正常工作。【参考方案2】:

您的问题有不同的解决方案。

解决方案 1: 每当用户注销时,您都可以从 coredata 中清除用户 ID 和密码。所以用户下次登录时,不会再添加相同的用户id。 (我更喜欢这个解决方案)

解决方案 2: 如果您真的不想在用户注销时清除用户 id,您可以在登录前检查用户 id 是否已经存在于核心数据中。如果它已经存在,则无需再次添加。您可以根据需要覆盖任何参数(但我基本上不喜欢这个参数,因为如果您有后端服务器和数据库来跟踪已登录的用户,则无需在 coredata 中保存任何详细信息。)

代码中的严重问题: 不要将密码等信息保存在 coredata 中,因为它缺乏隐私性。如果您真的想保存密码,可以将其保存在钥匙串中。有很多第三方类可用(例如:https://github.com/samsoffes/sskeychain)

编辑

首先,您需要从 coredata 中获取所有用户 ID

AppDelegate *appDelegate =[[UIApplication sharedApplication]delegate];

NSManagedObjectContext *context = [appDelegate managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:@"LoginUser"];

NSError *error = nil;

NSArray *results = [context executeFetchRequest:request error:&error];

if (error != nil) 

   NSLog(@"Coredata fetch failed");

else 
   BOOL userPresent = NO;
   for(NSManagedObject *user in results)
      if([[user objectForKey:@"userid"] isEqualToString:self.tx_userid.text])
         userPresent = YES;
   
   if(userPresent == YES)
     //user is present in DB
   else
     //new user

【讨论】:

我不希望用户注销时间清除数据库中的数据。我只想存储用户 id 而不是存储在数据库中的密码。 此用户 ID 有助于实现切换器功能。 如果您不想清除数据,请继续使用第二种方法。每次用户登录时,从您的 coredata 实体中获取所有条目并检查它是否包含新输入的用户 ID。如果存在,则可以使用相同的对象,否则创建一个新的 请解释一些代码,因为我尝试了很多次但没有正常工作。如果 else 条件不能正常工作。我不知道请解释一些代码。如何做到这一点。 你在吗,请帮忙【参考方案3】:

只需获取userId 之类的用户数据并检查id 是否已存在于数据库中,因此不要在本地数据库中再次保存用户数据,这将解决您的数据冗余问题。将emailId 视为userId,它对所有用户都是独一无二的。

获取当前userId检查并创建一个全局BOOL变量来指示是否需要保存用户数据。

获取数据的代码:

AppDelegate *appDelegate =[[UIApplication sharedApplication]delegate];

NSManagedObjectContext *context = [appDelegate managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:@"entityName"];

NSError *error = nil;

NSArray *results = [context executeFetchRequest:request error:&error];

if (error != nil) 

   //Deal with failure

else 
    for(NSManagedObject *user in results)
        if([[user objectForKey:@"userid"] isEqualToString:currentUserId])
            userPresent = YES;    // global bool variable
       
    if(userPresent == YES)
        // no action needed 
    else
        // call method to save user data 
        [self saveUserInfo];  
    


-(void) saveUserInfo
    // code here to save data inside db

现在使用结果数组,它已在其中获取数据。

【讨论】:

请解释如何检查条件以及如何检查已存储的通过对象? 您在其他情况下的回答我在数据库中存储了新数据? 什么是 userPresent。阿伦先生解决了我的问题。感谢您付出宝贵的时间。 :) userPresent 是您在类的 dec 部分中声明的全局变量。欢迎使用。

以上是关于如何创建登录条件和核心数据表值不能存储两次的主要内容,如果未能解决你的问题,请参考以下文章

核心数据难题:不能两次调用 NSFetchedResults

如何将 UIButton 值存储在核心数据中?

登录时多个用户访问的核心数据值(iOS Swift)

核心数据 - 不能存储两个单独的实体

如何从本地存储中获取每个用户在 laravel 6 中登录的数据?

登录时由多个用户访问的核心数据值(iOS Swift)