iOS开发:不同手机设备登陆同一账号,实现踢人掉线功能

开发中,我们一般是不允许两个或者多个手机登陆同一个账号的,如果有别的手机登陆了这个账号,那么其它在登陆这个账号的手机就要被踢掉线;

iOS开发:不同手机设备登陆同一账号,实现踢人掉线功能_第1张图片
踢人

如何实现这一功能呢,其实大部分的工作都是后台的;我们在登陆注册的时候,云端会给我们生成一个cookie(我们不需要关心cookie是什么,里面可能包含了userId和deviceId),我的做法是把cookie存在本地;

我们一般都有自己的网络请求类,一般都是对AFNetworking的封装,如果有别的手机B登陆了A这个账号,此时A这个手机再进行网络请求时,我们在封装的请求类里面截取每次的请求结果,后台会给一个错误的请求结果(如请求的result=-62),我们根据这个请求作出操作,以上是开发思路,代码过程如下:

.h代码(此处我只写了Get请求,Post请求一样需要处理,限于篇幅长度...)

#import 

typedef void (^SuccessBlock)(NSDictionary *data);
typedef void (^FailureBlock)(NSError *error);

@interface SYNetworkingManager : NSObject

@property (nonatomic, copy) SuccessBlock successBlock;
@property (nonatomic, copy) FailureBlock failureBlock;

/**
 *  发送get请求
 *
 *  @param URLString  请求的网址字符串
 *  @param parameters 请求的参数
 *  @param success    请求成功的回调
 *  @param failure    请求失败的回调
 */
+ (void)getWithURLString:(NSString *)urlString
              parameters:(id)parameters
                 success:(SuccessBlock)successBlock
                 failure:(FailureBlock)failureBlock;

@end

.m代码(关键是截取请求结果)

+ (void)getWithURLString:(NSString *)urlString
              parameters:(id)parameters
                 success:(SuccessBlock)successBlock
                 failure:(FailureBlock)failureBlock
{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    manager.requestSerializer.timeoutInterval = 5;
    [manager GET:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (successBlock) {
            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil];
            //每次请求到数据之后,都去分析这个数据是否是后台返回的被踢掉的信息
            [SYNetworkingManager kickPlayer:dic];
            successBlock(dic);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failureBlock) {
            failureBlock(error);
            NSLog(@"网络异常 - T_T%@", error);
        }
    }];
}

+ (void)kickPlayer:(NSDictionary *)dataDic
{
     //如果是后台返回的被踢掉的信息
    if ([dataDic[@"result"] integerValue] == -62) {
          //则发送一个通知
        [[NSNotificationCenter defaultCenter] postNotificationName:@"kickPlayer" object:dataDic];
    }
}

我们只需要在AppDelegate中注册通知,执行想要执行的方法操作

//APP在活跃状态
- (void)applicationDidBecomeActive:(UIApplication *)application {
    //注册通知,不同手机登陆同一账号,踢人
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kickPlayer:) name:@"kickPlayer" object:nil];
}

//APP在非活跃状态
- (void)applicationWillResignActive:(UIApplication *)application {
    //移除踢人的监听
    [[NSNotificationCenter defaultCenter] removeObserver:@"kickPlayer"];
}

//收到通知的处理
- (void)kickPlayer:(NSNotification *)notification
{
     //如果本地存储的cookie存在
    if ([K_UserDefaults objectForKey:K_User_Cookie]) {
          //删除cookie,并弹出提示框
        [K_UserDefaults removeObjectForKey:K_User_Cookie];
        NSDictionary *dic = notification.object;
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:dic[@"message"] delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
        alertView.tag = 100;
        [alertView show];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (alertView.tag == 100) { //踢人
        //这个主要是更换window的根视图控制器,弹出登陆界面
        self.window.rootViewController = self.loginVC;
    }
}

如果哪位大神觉得写得不好的话,轻喷(毕竟,我还只是个孩子),如果有好的想法,希望留言,我好借鉴;

你可能感兴趣的:(iOS开发:不同手机设备登陆同一账号,实现踢人掉线功能)