iOS开发-检查版本更新与强制更新控制
iOS开发-检查版本更新与强制更新控制。
在开发中经常遇到需要检查版本,检查版本及请求appstoreLookUrl查看版本号与当前的版本号进行比对,看是否需要更新。强制更新控制,是将获取到当前版本号传给服务端,服务端判断当前的版本是否需要强制升级。
一、app升级检查
发送请求系统NSURLConnection sendAsynchronousRequest
代码如下
SDVersionManager.h
#import <Foundation/Foundation.h>@interface SDVersionManager : NSObject<NSCoding>@property (nonatomic,strong) NSString *lastVersionCode; //版本code@property (nonatomic,strong) NSString *lastVersion; //保存最新的版本lastVersion@property (nonatomic,strong) NSString *versionNotes; //版本更新的记录releaseNotes+ (instancetype)sharedInstance;/**检测版本更新,如果有新版本,提醒用户更新,提醒一次@param needUpdate 需要更新的回调@param failure 不需要更新*/
+ (void)checkAppVersion:(void (^) (void))needUpdatefailure:(void (^) (void))failure;@end#pragma mark - SDVersionManagerDB@interface SDVersionManagerDB : NSObject+ (instancetype)sharedInstance;/**获取自定义对象UpdatedVersion实体,反序列化操作@return UpdatedVersion 实体*/
- (SDVersionManager *)loadLastVersion;/**保存自定义对象序列号@param version UpdatedVersion实体@return 是否保存成功*/
- (BOOL)saveLastVersion:(SDVersionManager *)version;@end
SDVersionManager.m
#import "SDVersionManager.h"
#import "SDContextManager.h"#define kDataFileVersion @"UpdatedVersion"
#define kDocumentPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]@class SDVersionManagerDB;
@implementation SDVersionManager
/**单例模式使用 dispatch_once_t if不是线程安全的@return 实例对象*/
+ (instancetype)sharedInstance
{static SDVersionManager *_sharedInstance = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{_sharedInstance = [[SDVersionManagerDB sharedInstance] loadLastVersion];if (_sharedInstance == nil) {_sharedInstance = [[SDVersionManager alloc] init];_sharedInstance.lastVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];}});return _sharedInstance;
}- (void)encodeWithCoder:(NSCoder *)aCoder {[aCoder encodeObject:_lastVersionCode forKey:NSStringFromSelector(@selector(lastVersionCode))];[aCoder encodeObject:_lastVersion forKey:NSStringFromSelector(@selector(lastVersion))];[aCoder encodeObject:_versionNotes forKey:NSStringFromSelector(@selector(versionNotes))];
}- (id)initWithCoder:(NSCoder *)aDecoder {if (self = [super init]) {_lastVersionCode = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(lastVersionCode))];_lastVersion = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(lastVersion))];_versionNotes = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(versionNotes))];}return self;
}/**检测版本更新,如果有新版本,提醒用户更新,提醒一次@param needUpdate 需要更新的回调@param failure 不需要更新*/
+ (void)checkAppVersion:(void (^) (void))needUpdatefailure:(void (^) (void))failure {NSURL *appstoreUrl = [NSURL URLWithString:[SDContextManager shareInstance].appstoreLookUrl];NSURLRequest *request = [NSURLRequest requestWithURL:appstoreUrl];NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];NSString *bundleCurrentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];__weak typeof(currentVersion) weakCurrentVersion = currentVersion;__weak typeof(bundleCurrentVersion) weakBundleCurrentVersion = bundleCurrentVersion;[NSURLConnection sendAsynchronousRequest:requestqueue:[NSOperationQueue mainQueue]completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {if (!connectionError) {NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&connectionError];NSArray *results = [dic objectForKey:@"results"];if ([results count] > 0) {NSDictionary *resultValue = [results objectAtIndex:0];NSString *versionStr = [resultValue objectForKey:@"version"];NSString *version = [[resultValue objectForKey:@"version"] stringByReplacingOccurrencesOfString:@"." withString:@""];NSString *note = [resultValue objectForKey:@"releaseNotes"];NSString *curVersion = [weakCurrentVersion stringByReplacingOccurrencesOfString:@"." withString:@""];NSString *curBundleVersion = [weakBundleCurrentVersion stringByReplacingOccurrencesOfString:@"." withString:@""];[SDVersionManager sharedInstance].versionNotes = note;if ([curVersion integerValue] < [version integerValue]) {//当前版本比appstore上低NSString *alastVerstion = [SDVersionManager sharedInstance].lastVersion;if (alastVerstion && version && ([alastVerstion integerValue] < [version integerValue])) {[SDVersionManager sharedInstance].lastVersion = version;[SDVersionManager sharedInstance].lastVersionCode = versionStr;if (needUpdate) {needUpdate();}} else {if (failure) {failure();}}} else if ([curVersion integerValue] <= [version integerValue]) {//当前版本比appstore上相同[SDVersionManager sharedInstance].lastVersion = version;[SDVersionManager sharedInstance].lastVersionCode = versionStr;if (failure) {failure();}} else if ([curVersion integerValue] > [version integerValue]) {//当前版本比appstore上高[SDVersionManager sharedInstance].lastVersion = version;[SDVersionManager sharedInstance].lastVersionCode = versionStr;if (failure) {failure();}}[[SDVersionManagerDB sharedInstance] saveLastVersion:[SDVersionManager sharedInstance]];}} else {if (failure) {failure();}}}];
}@end#pragma mark - SDVersionManagerDB@implementation SDVersionManagerDB+ (instancetype)sharedInstance {static SDVersionManagerDB *_sharedInstance = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{_sharedInstance = [[SDVersionManagerDB alloc] init];});return _sharedInstance;
}/**获取自定义对象UpdatedVersion实体,反序列化操作@return UpdatedVersion 实体*/
- (SDVersionManager *)loadLastVersion {NSString *dataFile = [NSString stringWithFormat:@"%@/%@", kDocumentPath, kDataFileVersion];@try{SDVersionManager *version = (SDVersionManager *)[NSKeyedUnarchiver unarchiveObjectWithFile:dataFile];if (version) {return version;}}@catch (NSException *e){}return nil;
}/**保存自定义对象序列化@param version UpdatedVersion实体@return 是否保存成功*/
- (BOOL)saveLastVersion:(SDVersionManager *)version {NSData *data = [NSKeyedArchiver archivedDataWithRootObject:version];NSString *dataFile = [NSString stringWithFormat:@"%@/%@", kDocumentPath, kDataFileVersion];return [data writeToFile:dataFile atomically:YES];
}@end
二、强制升级控制
强制更新控制,是将获取到当前版本号传给服务端,服务端判断当前的版本是否需要强制升级。
这块暂时就不写请求服务端的代码了。
三、小结
iOS开发-检查版本更新与强制更新控制。
在开发中经常遇到需要检查版本,检查版本及请求appstoreLookUrl查看版本号与当前的版本号进行比对,看是否需要更新。强制更新控制,是将获取到当前版本号传给服务端,服务端判断当前的版本是否需要强制升级。
学习记录,每天不停进步。
相关文章:
iOS开发-检查版本更新与强制更新控制
iOS开发-检查版本更新与强制更新控制。 在开发中经常遇到需要检查版本,检查版本及请求appstoreLookUrl查看版本号与当前的版本号进行比对,看是否需要更新。强制更新控制,是将获取到当前版本号传给服务端,服务端判断当前的版本是否…...
自动化运维工具——Ansible
自动化运维工具——Ansible 一、Ansible概述二、ansible 环境安装部署1.管理端安装 ansible2.ansible 目录结构3.配置主机清单4.配置密钥对验证 三、ansible 命令行模块1.command 模块2.shell 模块3.cron 模块4.user 模块5.group 模块6.copy 模块7.file 模块8.hostname 模块9&a…...
W2NER详解
论文:https://arxiv.org/pdf/2112.10070.pdf 代码:https://github.com/ljynlp/W2NER 文章目录 W2NER介绍模型架构解码 源码介绍数据输入格式模型代码 参考资料 W2NER 介绍 W2NER模型,将NER任务转化预测word-word(备注ÿ…...
ElementUI tabs标签页样式改造美化
今天针对ElementUI的Tabs标签页进行了样式修改,更改为如下图所属的样子。 在线运行地址:JSRUN项目-ElementUI tabs标签页样式改造 大家如果有需要可以拿来修改使用,下面我也简单的贴上代码,代码没有注释,很抱歉&#x…...
出海周报|Temu在美状告shein、ChatGPT安卓版上线、小红书回应闪退
工程机械产业“出海”成绩喜人,山东相关企业全国最多Temu在美状告shein,跨境电商战事升级TikTok将在美国推出电子商务计划,售卖中国商品高德即将上线国际图服务,初期即可覆盖全球超200个国家和地区ChatGPT安卓版正式上线ÿ…...
2023年7月26日 单例模式
单例模式 饿汉模式 package com.wz.cinema.platform.server.util;public class DataManager {/*** 单例模式:整个类在运行中只会有一个实例* 既然是在运行中只有一个实例,那么就必须* 考虑多线程环境** 单例模式分为懒汉模式和饿汉模式* 饿汉模式本身就是…...
[ 容器 ] Docker 安全及日志管理
目录 Docker 容器与虚拟机的区别Docker 存在的安全问题Docker 架构缺陷与安全机制Docker 安全基线标准容器相关的常用安全配置方法限制流量流向镜像安全避免Docker 容器中信息泄露DockerClient 端与 DockerDaemon 的通信安全 容器的安全性问题的根源在于容器和宿主机共享内核。…...
游游的排列构造
示例1 输入 5 2 输出 3 1 5 2 4 示例2 输入 5 3 输出 2 1 4 3 5 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N1e55; int n,k; int main(){scanf("%d%d",&n,&k);int xn-k1;int yn-k;int f1;for(int i1;i&l…...
拯救者Y9000K无线Wi-Fi有时不稳定?该如何解决?
由于不同品牌路由器的性能差异,无法完美兼容最新的无线网卡技术,在连接网络时(特别是网络负载较大的情况下),可能会出现Wi-Fi信号断开、无法网络无法访问、延迟突然变大的情况;可尝试下面方法进行调整。 1…...
【业务功能篇59】Springboot + Spring Security 权限管理 【下篇】
UserDetails接口定义了以下方法: getAuthorities(): 返回用户被授予的权限集合。这个方法返回的是一个集合类型,其中每个元素都是一个GrantedAuthority对象,表示用户被授予的权限。getPassword(): 返回用户的密码。这个方法返回的是一个字符…...
性能优化 - 前端性能监控和性能指标计算方式
性能优化 - 前端性能监控和性能指标计算方式 前言一. 性能指标介绍1.1 单一指标介绍1.2 指标计算① Redirect(重定向耗时)② AppCache(应用程序缓存的DNS解析)③ DNS(DNS解析耗时)④ TCP(TCP连接耗时)⑤ TTFB(请求响应耗时)⑥ Trans(内容传输耗时)⑦ DOM(DOM解析耗时) 1.3 FP(f…...
git stash clear清空本地暂存代码
git stash clear清空本地暂存代码 git stash 或者 git stash list 查看本地暂存的代码。 清除本地暂存的代码修改: git stash clear git回退代码仓库版本_git回退到之前的版本会影响本地代码嘛_zhangphil的博客-CSDN博客git回退代码版本_git回退到之前的版本会影…...
消防应急照明设置要求在炼钢车间电气室的应用
摘 要:文章以GB51309—2018《消防应急照明和疏散指示系统技术标准》为设计依据,结合某炼钢车间转炉项目的设计过程,在炼钢车间电气室的疏散照明和备用照明的设计思路、原则和方法等方面进行阐述。通过选择合理的消防应急疏散照明控制系统及灯具供配电方案…...
element 表单验证 深层验证绑定
直接上代码 :prop 和prop 都可以,vue2和vue3或者是element、elementplus都可以用 <template><div class"page page-table"><section class"page-query-form"><breadcrumb :hasLine"false" /></section&g…...
brew 换镜像网站
在国内,使用brew极慢. 因为它需要访问国外的一些服务器. 解决方法是使用国内的镜像站. 如果是首次安装: curl https://raw.githubusercontent.com/Homebrew/install/master/install.sh > install-brew.sh 然后,在下载的文件中, 修改BREW_REPO为: BREW_REPO"https…...
WIZnet W5500-EVB-Pico 静态IP配置教程(二)
W5500是一款高性价比的 以太网芯片,其全球独一无二的全硬件TCP、IP协议栈专利技术,解决了嵌入式以太网的接入问题,简单易用,安全稳定,是物联网设备的首选解决方案。WIZnet提供完善的配套资料以及实时周到的技术支持服务…...
R语言无法调用stats.dll的问题解决方案[补充]
写在前面 在去年10月份,出过一起关于R语言无法调用stats.dll的问题解决方案,今天(你看到后是昨天)不知道为什么,安装包,一直安装不了,真的是炸裂了。后面再次把R与Rstuido升级。说实话,我是真不…...
无线蓝牙耳机有什么推荐?怎么选择适合自己的耳机?七款蓝牙耳机分享
随着信息技术的不断发展,蓝牙耳机的不断发展也是必然的,可以说蓝牙耳机在大部分人们的生活中是不可缺少的一部分。那么我们该怎么去挑选出适合我们自己的需求的“蓝”朋友呢? 第一款:南卡小音舱lite2蓝牙耳机 推荐指数ÿ…...
【数据分析专栏之Python篇】四、pandas介绍
前言 在上一篇中我们安装和使用了Numpy。本期我们来学习使用 核心数据分析支持库 Pandas。 一、pandas概述 1.1 pandas 简介 Pandas 是 Python 的 核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。 …...
《算法竞赛·快冲300题》每日一题:“最小生成树”
《算法竞赛快冲300题》将于2024年出版,是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 最…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
