IOS开发学习日记(十七)

news2025/2/7 14:43:40

简单的第三方登录和分享功能

第三方登录系统

·URL Scheme:App间的跳转及通信

·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'

或者在腾讯开放平台中下载SDK:SDK下载 — QQ互联WIKI 

//
//  GSCLogin.h
//  GSCApp1
//
//  Created by gsc on 2024/6/22.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef void(^GSCLoginFinishBlock)(BOOL isLogin);

@interface GSCLogin : NSObject

@property(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.h"

@interface GSCLogin () <TencentSessionDelegate>

@property (nonatomic, strong, readwrite) TencentOAuth *oauth;
@property (nonatomic, copy, readwrite) GSCLoginFinishBlock finishBlock;
@property (nonatomic, assign, readwrite) BOOL isLogin;

@end

@implementation 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];
}


@end



@end

NS_ASSUME_NONNULL_END
//
//  GSCMineViewController.m
//  GSCApp1
//
//  Created by gsc on 2024/6/22.
//

#import "GSCMineViewController.h"
#import "GSCLogin.h"
#import "SDWebImage/SDWebImage.h"


@interface GSCMineViewController ()<UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong, readwrite) UITableView *tableView;
@property (nonatomic, strong, readwrite) UIView *tableViewHeaderView;
@property (nonatomic, strong, readwrite) UIImageView *headerImageView;

@end

@implementation GSCMineViewController

-(instancetype)init{
    self = [super init];
    if(self){
        self.tabBarItem.title = @"我的";
        self.tabBarItem.image = [UIImage imageNamed:@"icon.bundle/home@2x.png"];
        self.tabBarItem.selectedImage = [UIImage imageNamed:@"icon.bundle/home_selected@2x.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实现分享等逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1851003.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

068、PyCharm 关于Live Template模板

在 PyCharm 编辑器中&#xff0c;Live Templates 是一种功能强大的工具&#xff0c;可以帮助我们快速插入常用的代码片段或模板。 以下是在 PyCharm 中添加 Live Templates 的步骤&#xff1a; 添加 Live Templates 步骤&#xff1a; 打开 PyCharm 编辑器。 转到菜单栏中的 …

33 - 连续出现的数字(高频 SQL 50 题基础版)

33 - 连续出现的数字 -- 开窗函数lead(col,n) 统计窗口内往下第n行值 -- over(partition by xxx) 按照xxx所有行进行分组 -- over(partition by xxx order by aaa) 按照xxx分组&#xff0c;按照aaa排序select distinct num as ConsecutiveNums from(select num,# 从当前记录获…

Python——常用数据降维算法应用

随着数据的积累&#xff0c;数据的维度越来越高&#xff0c;高维的数据在带来更多信息的同时&#xff0c;也带来了信息冗余、计算困难等问题&#xff0c;所以对数据进行合理的降维&#xff0c;并保留主要信息非常重要。这些问题主要可以通过主成分分析及相关的降维算法来解决。…

国内外大模型生态发展报告!

很多同学只知类似Check GPT或者说对国内的一些比较了解&#xff0c;对国外的不太了解&#xff0c;所以在这总结。 1 大模型的发展 左表 名称参数特点发布时间GPT-215亿英文底模&#xff0c;开源2019年Google T5110亿多任务微调, 开源2019年GPT-3.51750亿人工反馈微调2022年M…

《计算机英语》 Unit 6 Internet 互联网

Section A Internet 互联网 The Internet is a global system of interconnected computer networks that use the standard Internet protocol suite (TCP/IP) to link several billion devices worldwide. 互联网是一个全球性的互连计算机网络系统&#xff0c;使用标准的互联…

Echarts实现动态背景

最近在公司工作中&#xff0c;遇到一个图表的需求&#xff0c;要求实现背景图是可以动态跟随最高点而改变位置的。 好玩的是&#xff0c;我实现了效果&#xff0c;但是没在官方配置项看到我这个用法的出处&#xff0c;所以记录一下。 话不多说&#xff0c;配置项也没什么好解释…

Redis的安装及详解

1.Redis介绍&#xff1f; 1.1 Redis是什么&#xff1f; Redis&#xff08;Remote Dictionary Server,远程字典服务器&#xff09;是一个开源免费的&#xff0c;用C语言编写的一个高性能的分布式内存数据库&#xff0c;基于内存运行并支持持久化的NoSQL数据库。是当前最热门的…

IPv6 address status lifetime

IPv6 地址状态转换 Address lifetime (地址生存期) 每个配置的 IPv6 单播地址都有一个生存期设置&#xff0c;该设置确定该地址在必须刷新或替换之前可以使用多长时间。某些地址设置为“永久”并且不会过期。“首选”和“有效”生存期用于指定其使用期限和可用性。 自动配置的…

开源与在线 M3U8 Downloader 项目介绍及使用指南

M3U8 是一种用于播放列表格式的文件类型&#xff0c;广泛应用于流媒体服务中&#xff0c;特别是 HLS&#xff08;HTTP Live Streaming&#xff09;协议。它包含了一系列的 TS&#xff08;Transport Stream&#xff09;视频片段地址&#xff0c;使得视频能够分段加载&#xff0c…

亿联 AM610 M.2 SSD PCIE 3.0X2 128GB测评

亿联 AM610 M.2 SSD PCIE 3.0X2 128GB测评 厂商&#xff1a;union memory国产固态硬盘SSD。 接口&#xff1a;PCIE 3.0X2 协议&#xff1a;支持NVME 1.协议 固件&#xff1a;固件版本号11.82 读取量&#xff1a;18TB左右 写入量&#xff1a;14TB左右&#xff0c;NAND闪存约被编…

win10/11磁盘管理

win10/11磁盘管理 合并磁盘分区的前提是你的两个磁盘区域是相邻的&#xff0c;比如如下&#xff1a; 如果需要吧这个磁盘进行分解&#xff0c;你可以选择压缩一部分磁盘或者是直接删除卷 我这里的话&#xff0c;因为压缩出来的卷和C盘好像是不相邻的&#xff08;我之前做过&…

kettle从入门到精通 第七十三课 ETL之kettle kettle调用http分页接口教程

场景&#xff1a;kettle调用http接口获取数据&#xff08;由于数据量比较大&#xff0c;鉴于网络和性能考虑&#xff0c;所以接口是个分页接口&#xff09;。 方案&#xff1a;构造页码list&#xff0c;然后循环调用接口。 1、总体设计 1&#xff09;、初始化分页参数pageNum1…

ICP、ISP及IAP烧录介绍

文章目录 不同的程序下载方式一、ICP:In-Circuit Programming二、ISP:In-System Programming三、IAP:In-Application ProgrammingIAP方案设计不同的程序下载方式 目前,单片机的程序烧录方式可以分为三种:ICP、ISP、IAP。 ICP:In Circuit Programing,在电路编程; ISP:…

【LLM】PISSA:一种高效的微调方法

前言 介绍PISSA前&#xff0c;先简单过一下LLMs微调经常采用的LoRA&#xff08;Low-Rank Adaptation&#xff09;微调的方法&#xff0c;LoRA 假设权重更新的过程中有一个较低的本征秩&#xff0c;对于预训练的权重参数矩阵 W 0 ∈ R d k W_0 ∈ R^{dk} W0​∈Rdk&#xff0c…

git常用操作汇总大全

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;入职小红书广告投放开发&#xff0c;很高兴认识大家&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博…

一图解释:监听dom滚动条是否滚动到底部

scrollTop&#xff1a;一个元素的内容垂直滚动的高度&#xff1b;scrollHeight &#xff1a;一个元素在不使用滚动条的情况下为了适应视口中所用内容所需的最小高度&#xff0c;包含内边距&#xff08;padding&#xff09;&#xff0c;不包含外边距&#xff08;margin&#xff…

NIST 电子病历中的临床决策部分的认证

写在正文之前 关于临床决策&#xff0c;有专门的行业协会收集并发布&#xff0c;我曾经注册过美国的一个网站&#xff0c;然后定期就会收到邮件通知新增了多少条临床决策。我记得我注册的是 NQF: Home (qualityforum.org) NQF: Home 美国国家标准与技术研究院&#xff08;Nat…

【SpringCloud-Seata源码分析2】

文章目录 分支事务注册-客户端分支事务服务端的执行 分支事务注册-客户端 第一篇我们将全局事务启动&#xff0c;以及开启源码分析完成了&#xff0c;现在我们需要看一下分支事务注册。 我们分支事务的开始需要从PreparedStatementProxy#executeUpdate中去看。 public class…

MatLab手把手搭建FOC控制环路(全部使用matlab自带模块)

MatLab手把手搭建FOC控制环路&#xff08;全部使用matlab自带模块&#xff09; Matlab添加模块只需要在空白处双击鼠标左键&#xff0c;输入模块的名字。 添加PMSM模块&#xff1a; Permanent Magnet Synchronous Machine 参数选择&#xff1a; 添加逆变器Two-Level Conver…