ios 手游SDK 开发教程

3,427 阅读7分钟

前言:

各位同学大家好 ,有一段时间没有见面了。 具体多久我也不清楚了, 最近在学习iOS 手游sdk 的开发 所以就想着写完 写一份教程分享给大家, 本人之前一直都是做安卓开发的 安卓 app和安卓手游SDK 开的都会。

需要用到的三方库

     pod 'AFNetworking'
    pod 'SDWebImage','4.0.0'
    pod 'WHToast','~>0.1.0'

效果图

6865547-3f15508c0d1d02ed.png image.png image.png

主要实现逻辑 手游SDK

初始化        init. 
登录            login  
支付            pay.  
区服登录    servicelogin. 
等级变化上报   updateuserinfo

接口设计

6865547-3f15508c0d1d02ed.png image.png image.png

//
//  NineFunSdk.h
//  016登录界面
//
//  Created by xuqing on 2022/4/26.
//

#import <Foundation/Foundation.h>
#import <UIkit/UIkit.h>
#import "RoleInfo.h"
#import "ServiceInfo.h"
NS_ASSUME_NONNULL_BEGIN

typedef void (^LoginFinishBlock)(BOOL success, id data);

typedef void (^InitFinishBlock)(BOOL success, NSString * data);
typedef void (^PayFinishBlock)(BOOL success, NSString * data);

typedef void (^ServiceBlock)(BOOL success);

typedef void (^UpdateUserInfoBlcok)(BOOL success);


@interface NineFunSdk : NSObject

+ (void)viewcontroller:(UIViewController *)controller sdkCheckLogin:(LoginFinishBlock)finishBlock;

+ (void)initSdk:(InitFinishBlock)finishBlock;

+ (void)pay:(PayFinishBlock)finishBlock;

+ (void)serviceinfo:(ServiceInfo*)getserviceinfo  serviceLogin:(ServiceBlock)finishBlock;

+ (void)roleinfo:(RoleInfo*)getroleinfo updateUserInfo:(UpdateUserInfoBlcok)finishBlock;


@end

NS_ASSUME_NONNULL_END

我们定义这些对外方法 当然你也可以写成类方法 然后写个单例 去掉也行 我这边方便就用 + 然后每个方法我们定义了 block回调 这个看具体需求 因为参考了安卓了那边写法 每个对外接口都给回调 我就都给加了

具体接口的实现

//
//  NineFunSdk.m
//
//  Created by xuqing on 2022/4/26.
//

#import "NineFunSdk.h"
#import "ViewController.h"
#import  <AFNetworking.h>
#import "NSString+Encrypt.h"
#import "RoleInfo.h"
#import "ServiceInfo.h"
#import "Md5Utils.h"


@implementation NineFunSdk



// 登录接口
+ (void)viewcontroller:(UIViewController *)controller sdkCheckLogin:(LoginFinishBlock)finishBlock{

    ViewController * viewController= [[ViewController alloc]init];
    viewController.logBlock = finishBlock;
    [controller presentViewController:viewController animated:YES completion:nil];
}

// 初始化接口
+ (void)initSdk:(InitFinishBlock)finishBlock{
    

    
}


//支付接口
+ (void)pay:(PayFinishBlock)finishBlock{
    
    
    
}

// 区服登录接口
+ (void)serviceinfo:(ServiceInfo*)getserviceinfo  serviceLogin:(ServiceBlock)finishBlock{
    
    NSLog(@"区服登录");
    NSString * sign = [NSString stringWithFormat:@"sid=%@role_id=%@role_anme=%@||0a649d6b-df9f-4583-bf7d-3fae84838519",getserviceinfo->_sid,getserviceinfo->_roleid,getserviceinfo->_rolename];
    
    
    NSLog(@" sign %@", sign);
    
   // NSString * getsign=[sign MD5];
    
    
    NSString * getsign=[Md5Utils getMd5_32Bit_String:sign isUppercase:NO];
    NSString * serviceLoginUrl=@"http://192.168.7.25:8090/boss/serviceinfo/servicelogin?";
    NSMutableString *geturl = [NSMutableString string];
     [geturl appendString:serviceLoginUrl];
     [geturl appendString:@"gid="];
     [geturl appendString:getserviceinfo->_gid];
     [geturl appendString:@"&"];
     [geturl appendString:@"sid="];
     [geturl appendString:getserviceinfo->_sid];
    [geturl appendString:@"&"];
    [geturl appendString:@"role_name="];
    [geturl appendString:getserviceinfo->_rolename];

    [geturl appendString:@"&"];
    [geturl appendString:@"role_level="];
    [geturl appendString:getserviceinfo->_rolelevel];

    [geturl appendString:@"&"];
    [geturl appendString:@"role_id="];
    [geturl appendString:getserviceinfo->_roleid];
    
    
    [geturl appendString:@"&"];
    [geturl appendString:@"sign="];
    [geturl appendString:getsign];
    
    NSString *url = [geturl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
//    NSLog(@"geturl --- %@",geturl);

    [[AFHTTPSessionManager manager]GET:url parameters:nil headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {
              NSLog(@"");
          } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
              NSLog(@"");
              NSLog(@"请求成功---%@",responseObject);
              NSLog(@"请求 msg ---%@",[responseObject objectForKey:(@"msg")]);
                  finishBlock(YES);
            
          } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
              NSLog(@"");
          }];
    

};


//等级变化上报接口
+ (void)roleinfo:(RoleInfo*)getroleinfo updateUserInfo:(UpdateUserInfoBlcok)finishBlock{
    

    NSLog(@"等级变化上报");
    
    
    NSString * sign = [NSString stringWithFormat:@"sid=%@role_id=%@role_anme=%@||0a649d6b-df9f-4583-bf7d-3fae84838519",getroleinfo->_sid,getroleinfo->_roleid,getroleinfo->_rolename];
    
    
    NSLog(@" sign %@", sign);
    
   // NSString * getsign=[sign MD5];
    
    
    NSString * getsign=[Md5Utils getMd5_32Bit_String:sign isUppercase:NO];
    NSLog(@"  getsign %@", getsign);
    
    
    
    NSString * serviceLoginUrl=@"http://192.168.7.25:8090/boss/roleinfo/submitroleinfo?";
    NSMutableString *geturl = [NSMutableString string];
     [geturl appendString:serviceLoginUrl];
     [geturl appendString:@"gid="];
     [geturl appendString:getroleinfo->_gid];
     [geturl appendString:@"&"];
     [geturl appendString:@"sid="];
     [geturl appendString:getroleinfo->_sid];
    [geturl appendString:@"&"];
    [geturl appendString:@"role_name="];
    [geturl appendString:getroleinfo->_rolename];

    [geturl appendString:@"&"];
    [geturl appendString:@"role_level="];
    [geturl appendString:getroleinfo->_rolelevel];

    [geturl appendString:@"&"];
    [geturl appendString:@"role_id="];
    [geturl appendString:getroleinfo->_roleid];
    
    [geturl appendString:@"&"];
    [geturl appendString:@"sign="];
    [geturl appendString:getsign];
    
    
    NSString *url = [geturl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
//    NSLog(@"geturl --- %@",geturl);

    [[AFHTTPSessionManager manager]GET:url parameters:nil headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {
              NSLog(@"");
          } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
              NSLog(@"");
              NSLog(@"请求成功---%@",responseObject);
              NSLog(@"请求 msg ---%@",[responseObject objectForKey:(@"msg")]);
                  finishBlock(YES);
              
            
          } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
              NSLog(@"");
          }];
   
}
@end

因为时间问题 我这边制作了 login 和servicelogin. updateuserinfo 这几个接口的实现

登录接口

// 登录接口
+ (void)viewcontroller:(UIViewController *)controller sdkCheckLogin:(LoginFinishBlock)finishBlock{

    ViewController * viewController= [[ViewController alloc]init];
    viewController.logBlock = finishBlock;
    [controller presentViewController:viewController animated:YES completion:nil];
}

登录接口我们需要传入 UIViewController 实例和 实现LoginFinishBlock 回调

登录界面逻辑

  • m 文件

//  LoginView.h
//  016登录界面
//  Created by xuqing on 2022/5/5.

#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
**@interface** LoginView : UIView{

    //登录界面的组成

    UILabel *_usernameLabel;

    UILabel * _passwordLabel;

    UITextField *_userTextfield;

    UITextField *_passwordfield;

    UIButton * _loginBtn;

    UIButton * _registerBtn;

    UIView * _blackBgV;

    UIView * _alertV;
}

**@property**(**retain**,**nonatomic**)UILabel * usernameLabel;

**@property**(**retain**,**nonatomic**)UILabel * pswLabel;

**@property**(**retain**,**nonatomic**)UITextField * userTextfield;

**@property**(**retain**,**nonatomic**)UITextField * pswfield;

**@property**(**retain**,**nonatomic**)UIButton * loginBtn ;

**@property**(**retain**, **nonatomic**)UIButton * registerBtn;

**@property**(**retain**, **nonatomic**)UIView * blackBgV;

**@property**(**retain**, **nonatomic**)UIView * alertV;

**@property** (**nonatomic**,**copy**)**void**(^logBlock)(**BOOL** success, **id** data);
- (**void**)show;
**@end**
NS_ASSUME_NONNULL_END
  • h 文件

//

//  LoginView.m

//  016登录界面

//  Created by xuqing on 2022/5/5.

#import "LoginView.h"

#import  <AFNetworking.h>

#import <WHToast.h>

#import "TextUtils.h"

#import "ToastUtils.h"

#import "RegisterView.h"

**@implementation** LoginView

**@synthesize** usernameLabel=_usernameLabel;

**@synthesize** pswLabel=_passwordLabel;

**@synthesize** userTextfield=_userTextfield;

**@synthesize** pswfield=_passwordfield;

**@synthesize** loginBtn=_loginBtn;

**@synthesize** registerBtn=_registerBtn;

**@synthesize** blackBgV=_blackBgV;

**@synthesize** alertV=_alertV;

- (**instancetype**)initWithFrame:(CGRect)frame

{

    **if** (**self** = [**super** initWithFrame:frame]) {

        [**self** setUpSubView];

    }

    **return** **self**;

}

- (**void**)setUpSubView

{

    

**self**.frame = [UIScreen mainScreen].bounds;

    

    // 初始化遮罩视图

    **self**.blackBgV = [[UIView alloc]initWithFrame:**self**.bounds];

    **self**.blackBgV.backgroundColor = [UIColor grayColor];

    **self**.blackBgV.alpha = 0;

    [**self** addSubview:**self**.blackBgV];

    

    // 初始化actionSheetView

    **self**.alertV = [[UIView alloc] initWithFrame:CGRectMake(30,**self**.bounds.size.height/2-120, **self**.bounds.size.width-60, 240)];

    **self**.alertV.backgroundColor = [UIColor whiteColor];

    **self**.alertV.layer.cornerRadius = 5;

    **self**.alertV.layer.masksToBounds = **YES**;

    **self**.alertV.alpha = 0;

    [**self** addSubview:**self**.alertV];

    

    

    _usernameLabel =[[UILabel alloc]init];

    _usernameLabel.frame=CGRectMake(60, 50, 60, 40);

    _usernameLabel.text=@"账号:";

    _usernameLabel.textColor=[UIColor blueColor];

    [**self**.alertV addSubview:_usernameLabel];

    _userTextfield =[[UITextField alloc] init];

    _userTextfield.frame=CGRectMake(100, 50,180, 40);

    _userTextfield.font= [UIFont systemFontOfSize:15];

    // 设置字体颜色

    _userTextfield.textColor=[UIColor blackColor];

     //设置边框的风格

     // UITextBorderStyleBezel bezel线框

     // UITextBorderStyleRoundedRect 圆角风格

     // UITextBorderStyleLine 线框风格

     // UITextBorderStyleNone  无边框风格

    _userTextfield.borderStyle= UITextBorderStyleRoundedRect;

\


    //设置虚拟键盘风格

    //UIKeyboardTypeDefault 默认风格

    //UIKeyboardTypeNumberPad 纯数字风格

    //UIKeyboardTypeNamePhonePad 字母和数字组合风格

    _userTextfield.keyboardType=UIKeyboardTypeNamePhonePad;

    _userTextfield.placeholder=@"请输入用户名...";

    //是否作为密码输入

    //YES 做为处理 圆点加密

    //NO: 正常显示输入的文字

    _userTextfield.secureTextEntry= **NO**;

    [**self**.alertV addSubview:  _userTextfield];

    _passwordLabel =[[UILabel alloc]init];

    _passwordLabel.frame=CGRectMake(60, 100, 60, 40);

    _passwordLabel.text=@"密码:";

    _passwordLabel.textColor=[UIColor blueColor];

    [**self**.alertV addSubview:_passwordLabel];


    _passwordfield =[[UITextField alloc] init];

    _passwordfield.frame=CGRectMake(100, 100,180, 40);

    _passwordfield.font= [UIFont systemFontOfSize:15];

    // 设置字体颜色

    _passwordfield.textColor=[UIColor blackColor];

     //设置边框的风格

     // UITextBorderStyleBezel bezel线框

     // UITextBorderStyleRoundedRect 圆角风格

     // UITextBorderStyleLine 线框风格

     // UITextBorderStyleNone  无边框风格

    _passwordfield.borderStyle= UITextBorderStyleRoundedRect;

    //设置虚拟键盘风格

    //UIKeyboardTypeDefault 默认风格

    //UIKeyboardTypeNumberPad 纯数字风格

    //UIKeyboardTypeNamePhonePad 字母和数字组合风格

    _passwordfield.keyboardType=UIKeyboardTypeNamePhonePad;

    _passwordfield.placeholder=@"请输入密码...";

    //是否作为密码输入

    //YES 做为处理 圆点加密

    //NO: 正常显示输入的文字

    _passwordfield.secureTextEntry= **YES**;

    [**self**.alertV addSubview:  _passwordfield];

    _loginBtn=[UIButton buttonWithType: UIButtonTypeRoundedRect];

    _loginBtn.frame=CGRectMake(80, 160, 80, 40);

    [_loginBtn setTitle:@"登录" forState:UIControlStateNormal];

    [_loginBtn addTarget:**self** action: **@selector**(login) forControlEvents:UIControlEventTouchUpInside];

    _loginBtn.backgroundColor=[UIColor blueColor];

    [_loginBtn setTitleColor: [UIColor whiteColor ] forState:UIControlStateNormal] ;

       //设置按钮颜色

     [_loginBtn setTitleColor: [UIColor grayColor] forState:UIControlStateHighlighted] ;

    [**self**.alertV addSubview:_loginBtn];

    _registerBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];

    _registerBtn.frame=CGRectMake(180, 160, 80, 40);

    [_registerBtn setTitle:@"注册" forState:UIControlStateNormal];

    [_registerBtn addTarget:**self** action: **@selector**(registerMethod) forControlEvents:UIControlEventTouchUpInside];

    _registerBtn.backgroundColor=[UIColor blueColor];

    [_registerBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

    [**self**.alertV addSubview:_registerBtn];

    

}




-(**void**)registerMethod{

    [**self** hidden];

    RegisterView * registerview=[[RegisterView alloc]init];

    registerview.registerBlock=_logBlock;

    [registerview show];

}

-(**void**)login{

    NSString * _strTextName=_userTextfield.text;

    NSString * _strTextPsw=_passwordfield.text;

    **if**(![TextUtils isBlankString:_strTextName]

       &&![TextUtils isBlankString:_strTextPsw]){

        NSLog(@"登录成功");

        NSLog(@"%@ %@",_strTextName,_strTextPsw);

        NSString * registerString=@"http://192.168.7.25:8090/boss/user/validlogin?";

        NSString * str1=@"username=";

        NSString * str2=@"password=";

        NSMutableString *geturl = [NSMutableString string];

         [geturl appendString:registerString];

         [geturl appendString:str1];

         [geturl appendString:_strTextName];

         [geturl appendString:@"&"];

         [geturl appendString:str2];

         [geturl appendString:_strTextPsw];

         NSLog(@" geturl  ---  > %@",geturl);

              [[AFHTTPSessionManager manager]GET:geturl parameters:**nil** headers:**nil** progress:^(NSProgress * **_Nonnull** downloadProgress) {

                        NSLog(@"");

                    } success:^(NSURLSessionDataTask * **_Nonnull** task, **id**  **_Nullable** responseObject) {

                        NSLog(@"");

                        NSLog(@"请求成功---%@",responseObject);

                        NSLog(@"请求 msg ---%@",[responseObject objectForKey:(@"msg")]);

                        NSString * msg=[responseObject objectForKey:(@"msg")];

                        NSInteger code = [[responseObject objectForKey:(@"code")] integerValue];

                        **if**(code==200){

                            **if** (**self**.logBlock) {

                                **self**.logBlock(**YES**, responseObject);

                                [**self** hidden];

                            }

                        }**else**{

                            [ToastUtils showInfo:msg];

                        }

                    } failure:^(NSURLSessionDataTask * **_Nullable** task, NSError * **_Nonnull** error) {

                        NSLog(@"");

                    }];

                }**else** {

                  
       [ToastUtils showInfo:@"账号或者密码不能为空" ];

    }
}
- (**void**)show {

    [**self** setUpSubView];

    [[UIApplication sharedApplication].keyWindow addSubview:**self**];

    **self**.hidden = **NO**;

    [UIView animateWithDuration:0.3 animations:^{

        **self**.alertV.alpha = 1;

        **self**.blackBgV.alpha = 0.5;

    } completion:^(**BOOL** finished) {

        

    }];

  
}
- (**void**)hidden {

    **__block** **typeof**(**self**) weakSelf = **self**;

    [UIView animateWithDuration:0.3 animations:^{

        **self**.alertV.alpha = 0;

        **self**.blackBgV.alpha = 0;

    } completion:^(**BOOL** finished) {

        weakSelf.hidden = **YES**;

        [weakSelf removeFromSuperview];

    }];

}

#pragma mark **-- 遮罩视图点击**
- (**void**)tapClick:(UIGestureRecognizer *)tap {
    NSLog(@"遮罩视图点击");
}
**@end**


我们看到 我们在登录的viewcontroller 也定义了一个block 然后我们跳转的时候将外部传进来的 block 赋值给我们在登录定义的block.然后我们在登录网络请求成功以后 回调我们数据回去即可。 还有注册的viewcontroller 也是同理的 我就不展开讲了 也是注册成功 将服务端返回的数据结构 回调回去

数据上报逻辑 servicelogin

// 区服登录接口
+ (void)serviceinfo:(ServiceInfo*)getserviceinfo  serviceLogin:(ServiceBlock)finishBlock{
    
    NSLog(@"区服登录");
    NSString * sign = [NSString stringWithFormat:@"sid=%@role_id=%@role_anme=%@||0a649d6b-df9f-4583-bf7d-3fae84838519",getserviceinfo->_sid,getserviceinfo->_roleid,getserviceinfo->_rolename];
    NSLog(@" sign %@", sign);

    NSString * getsign=[Md5Utils getMd5_32Bit_String:sign isUppercase:NO];
    NSLog(@" getsign --- >  %@" ,getsign);

    NSString * serviceLoginUrl=@"http://192.168.7.25:8090/boss/serviceinfo/servicelogin?";
    NSMutableString *geturl = [NSMutableString string];
     [geturl appendString:serviceLoginUrl];
     [geturl appendString:@"gid="];
     [geturl appendString:getserviceinfo->_gid];
     [geturl appendString:@"&"];
     [geturl appendString:@"sid="];
     [geturl appendString:getserviceinfo->_sid];
    [geturl appendString:@"&"];
    [geturl appendString:@"role_name="];
    [geturl appendString:getserviceinfo->_rolename];

    [geturl appendString:@"&"];
    [geturl appendString:@"role_level="];
    [geturl appendString:getserviceinfo->_rolelevel];

    [geturl appendString:@"&"];
    [geturl appendString:@"role_id="];
    [geturl appendString:getserviceinfo->_roleid];
    
    
    [geturl appendString:@"&"];
    [geturl appendString:@"sign="];
    [geturl appendString:getsign];
   
    NSString *url = [geturl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//    NSLog(@"geturl --- %@",geturl);
    [[AFHTTPSessionManager manager]GET:url parameters:nil headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {
              NSLog(@"");
          } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
              NSLog(@"");
              NSLog(@"请求成功---%@",responseObject);
              NSLog(@"请求 msg ---%@",[responseObject objectForKey:(@"msg")]);
                  finishBlock(YES);
            
          } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
              NSLog(@"");
          }];
};




我们同样定义对外接口方法 需要传入 ServiceInfo 模型实例 然后实现 ServiceBlock 回调 然后我们在这个方法内部去请求服务端进去游戏里面数据上报逻辑 。

具体接入效果

  • 登录接入

//登录
- (IBAction)login:(id)sender {
    [NineFunSdk viewcontroller:self sdkCheckLogin:^(BOOL success, id data) {
        NSLog(@"回调成功成功---%@",data);
    }];
}
  • 数据上报 servicelogin

// 区服登录上报
- (IBAction)servicelogin:(id)sender {
    ServiceInfo * serviceinfo=[ServiceInfo new];
    serviceinfo->_sid=@"1111";
    serviceinfo->_gid=@"424251";
    serviceinfo->_roleid=@"旋涡名人";
    serviceinfo->_rolename=@"最强王者";
    serviceinfo->_rolelevel=@"214141";
    
    [NineFunSdk serviceinfo:serviceinfo serviceLogin:^(BOOL success) {
        NSLog(@"区服登录");
    }];
}
  • 数据上报 updateuserinfo

// 等级变化上报
- (IBAction)updateuserinfo:(id)sender {
    RoleInfo * roleinfo= [RoleInfo new];
    roleinfo->_gid=@"12232";
    roleinfo->_roleid=@"422422";
    roleinfo->_rolename=@"醉生梦死";
    roleinfo->_sid=@"测试服务器";
    roleinfo->_rolelevel=@"191";
    [NineFunSdk roleinfo:roleinfo updateUserInfo:^(BOOL success) {
        NSLog(@"等级变化上报");
    }];
}

整个iOS 手机SDK 大概就讲完了

最后总结:

有很多同学这时候就说 做成SDK 应该最后要打包成静态库才对吧 。是的没错 这一期我只是讲大概思路 因为我也不会打包静态库 所以我也还在学习 后面继续更新哈代码里面很多的三方库其实也不是这样去用的 我们应该直接去拉代码 不应该用 pod file 这样去依赖 我也是为了方便。最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦!