建立网站 要怎么做,做网站的属于什么岗位,网络营销培训,智慧旅游门户网站建设简单的第三方登录和分享功能
第三方登录系统
URL Scheme#xff1a;App间的跳转及通信
App间跳转场景
登陆系统#xff1a; 跨平台#xff0c;跨App 标记用户#xff0c;个性化的推送 使用第三方登录#xff08;减少注册成本 / 无须维护敏感信息#xff09; 微信 / Q…简单的第三方登录和分享功能
第三方登录系统
·URL SchemeApp间的跳转及通信
·App间跳转场景
·登陆系统 ·跨平台跨App ·标记用户个性化的推送 ·使用第三方登录减少注册成本 / 无须维护敏感信息 ·微信 / QQ / 微博 / facebook / Twitter
·登录系统通用技术 ·framework的使用和集成 ·常用的第三方认证和账户体系 ·业务逻辑的设计和实现
静态库 动态库 ·库Library ·代码共享 / 保护核心代码 ·提高编译速度 / 减少代码提及系统 ·静态库 ·.a文件 ·编译时期拷贝 ·增大代码提及 / 不可改变 ·动态库 ·.dylib ·编译时期只存储引用运行时加载到内存 ·无须拷贝减少体积 / 性能损失 / 安全性 IOS中静态库的创建和使用
·Framework ·资源的打包方式 ·支持静态库 / 动态库 ·系统的Framework都是动态库 ·支持Extension共享 - Embedded framework
静态库的制作 ·创建static Library实现业务逻辑 ·设置需要暴露的头文件 ·模拟器 / 设备分别编译 / 设置Settings ·合并静态库lipo - create ***.a ***.a -output ***.a
·静态库.a本身是二进制文件
·需要手动引入头文件使用
·一般需要设置Other Linker Flags等 IOS中Framework的制作和使用
·创建framework实现业务逻辑
·设置public的头文件
·模拟器 / 设备 / 分别编译 / 设置Settings
·合并framework ·引入framework 即包含头文件
·头文件的引入
·一般需要设置Other Linker Flags等 OAuth OpenID
OAuth授权 ·第三方登录使用用户名 / 密码安全 / 用户成本 ·开放协议标准的方式去访问需要用户授权的API服务
OpenID ·明文的安全性 / 不同的业务无法隔离 ·隐藏明文 / 每个App独立的openID 集成QQ SDK实现登录和分享功能
首先下载TencentOpenApi在podfile中添加
# pod TencentOpenAPI
pod TencentOpenAPI, :git https://github.com/everfire130/TencentOpenAPI.git
或者在腾讯开放平台中下载SDKSDK下载 — QQ互联WIKI
//
// GSCLogin.h
// GSCApp1
//
// Created by gsc on 2024/6/22.
//#import Foundation/Foundation.hNS_ASSUME_NONNULL_BEGINtypedef void(^GSCLoginFinishBlock)(BOOL isLogin);interface GSCLogin : NSObjectproperty(nonatomic,strong,readonly)NSString *nick;
property(nonatomic,strong,readonly)NSString *address;
property(nonatomic,strong,readonly)NSString *avatarUrl;(instancetype)sharedLogin;#pragma - mark - 登录-(BOOL)isLogin;
-(void)loginWithFinishBlock:(GSCLoginFinishBlock)finishBlock;
-(void)logOut;#pragma - mark - 分享
-(void)shareToQQWithArticleUrl:(NSURL *)articleUrl;//
// GSCLogin.m
// GSCApp1
//
// Created by gsc on 2024/6/22.
//#import GSCLogin.h
#import TencentOpenAPI/QQApiInterface.h
#import TencentOpenAPI/TencentOAuth.hinterface GSCLogin () TencentSessionDelegateproperty (nonatomic, strong, readwrite) TencentOAuth *oauth;
property (nonatomic, copy, readwrite) GSCLoginFinishBlock finishBlock;
property (nonatomic, assign, readwrite) BOOL isLogin;endimplementation GSCLogin(instancetype)sharedLogin{static GSCLogin *login;static dispatch_once_t onceToken;dispatch_once(onceToken, ^{login [[GSCLogin alloc] init];});return login;
}-(instancetype)init{self [super init];if(self){_isLogin NO;_oauth [[TencentOAuth alloc] initWithAppId:123456 andDelegate:self];}return self;
}
#pragma - mark - 登录-(BOOL)isLogin{return _isLogin;
}
-(void)loginWithFinishBlock:(GSCLoginFinishBlock)finishBlock{_finishBlock [finishBlock copy];_oauth.authMode kAuthModeClientSideToken;[_oauth authorize:[kOPEN_PERMISSION_GET_USER_INFO,kOPEN_PERMISSION_GET_SIMPLE_USER_INFO,kOPEN_PERMISSION_ADD_ALBUM,kOPEN_PERMISSION_ADD_TOPIC,kOPEN_PERMISSION_CHECK_PAGE_FANS,kOPEN_PERMISSION_GET_INFO,kOPEN_PERMISSION_GET_OTHER_INFO,kOPEN_PERMISSION_LIST_ALBUM,kOPEN_PERMISSION_UPLOAD_PIC,kOPEN_PERMISSION_GET_VIP_INFO,kOPEN_PERMISSION_GET_VIP_RICH_INFO]];}
-(void)logOut{[_oauth logout:self];_isLogin NO;
}#pragma mark - delegate-(void)tencentDidLogin{_isLogin YES;[_oauth getUserInfo];
}-(void)tencentDidNotLogin:(BOOL)cancelled{if(_finishBlock){_finishBlock(NO);}
}-(void)tencentDidNotNetWork{}-(void)tencentDidLogout{}-(void)getUserInfoResponse:(APIResponse *)response{NSDictionary *userInfo response.jsonResponse;_nick userInfo[nickname];_address userInfo[city];_avatarUrl userInfo[figureurl_qq_2];if(_finishBlock){_finishBlock(YES);}
}
#pragma - mark - 分享
-(void)shareToQQWithArticleUrl:(NSURL *)articleUrl{QQApiNewsObject *newsObj [QQApiNewsObject objectWithURL:articleUrl title:ios description:iosDevLearn previewImageURL:nil];SendMessageToQQReq *req [SendMessageToQQReq reqWithContent:newsObj];__unused QQApiSendResultCode sent [QQApiInterface SendReqToQZone:req];
}endendNS_ASSUME_NONNULL_END//
// GSCMineViewController.m
// GSCApp1
//
// Created by gsc on 2024/6/22.
//#import GSCMineViewController.h
#import GSCLogin.h
#import SDWebImage/SDWebImage.hinterface GSCMineViewController ()UITableViewDelegate, UITableViewDataSourceproperty (nonatomic, strong, readwrite) UITableView *tableView;
property (nonatomic, strong, readwrite) UIView *tableViewHeaderView;
property (nonatomic, strong, readwrite) UIImageView *headerImageView;endimplementation GSCMineViewController-(instancetype)init{self [super init];if(self){self.tabBarItem.title 我的;self.tabBarItem.image [UIImage imageNamed:icon.bundle/home2x.png];self.tabBarItem.selectedImage [UIImage imageNamed:icon.bundle/home_selected2x.png];}return self;
}- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor [UIColor whiteColor];[self.view addSubview:({_tableView [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];_tableView.delegate self;_tableView.dataSource self;_tableView;})];
}#pragma mark - Navigation-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{return 2;
}-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{UITableViewCell *cell [tableView dequeueReusableCellWithIdentifier:mineTableViewCell];if(!cell){cell [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:mineTableView];}return cell;
}-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{return 60;
}-(nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{if(!_tableViewHeaderView){_tableViewHeaderView [[UIView alloc] initWithFrame:CGRectMake(0, 30, self.view.frame.size.width, self.view.frame.size.height)];_tableViewHeaderView.backgroundColor [UIColor whiteColor];[_tableViewHeaderView addSubview:({_headerImageView [[UIImageView alloc] initWithFrame:CGRectMake(0, 30, self.view.frame.size.width, self.view.frame.size.height)];_headerImageView.backgroundColor [UIColor whiteColor];_headerImageView.contentMode UIViewContentModeScaleAspectFit;_headerImageView.clipsToBounds YES;_headerImageView.userInteractionEnabled YES;_headerImageView;})];[_tableViewHeaderView addGestureRecognizer:({UITapGestureRecognizer *tapGesture [[UITapGestureRecognizer alloc] initWithTarget:self action:selector(_tapImage)];tapGesture;})];}return _tableViewHeaderView;
}-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{return 200;
}-(void)tableView:(UITableView *)tableView willDisplayHeaderView:(nonnull UIView *)view forSection:(NSInteger)section{if(![[GSCLogin sharedLogin] isLogin]){[_headerImageView setImage:[UIImage imageNamed:icon.bundle/prettydog.png]];}else{[self.headerImageView sd_setImageWithURL:[NSURL URLWithString:[GSCLogin sharedLogin].avatarUrl]];}
}-(void)tableView:(UITableView *)tableView willDisplayCell:(nonnull UITableViewCell *)cell forRowAtIndexPath:(nonnull NSIndexPath *)indexPath{if(indexPath.row 0){cell.textLabel.text [[GSCLogin sharedLogin] isLogin] ? [GSCLogin sharedLogin].nick: 昵称;}else{cell.textLabel.text [[GSCLogin sharedLogin] isLogin] ? [GSCLogin sharedLogin].address:地区;}}#pragma mark --(void)_tapImage{__weak typeof(self) weakSelf self;if(![[GSCLogin sharedLogin] isLogin]){// 如果未登录则拉起登录[[GSCLogin sharedLogin] loginWithFinishBlock:^(BOOL isLogin){__strong typeof(self) strongSelf self;if(isLogin){[strongSelf.tableView reloadData];}}];}else{// 已登录则退出登录[[GSCLogin sharedLogin] logOut];[self.tableView reloadData];}
}end集成SDK实现登录与分享 ·申请接入获取appid和apikey ·集成SDK设置对应的settings及URL Scheme ·业务逻辑的基础UI和交互登录 / 分享 ... ·通过用户登录验证和授权获取Access Token ·通过Access Token获取用户的OpenID ·通过OpenAPI请求访问或修改用户授权的资源 ·客户端保存相应用户信息按需展示 ·调用其它API实现分享等逻辑