OC 技术 苹果内购

一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。

OC 技术 苹果内购视频解说

苹果内购(视频讲解的封装)代码下载地址

前言

之前做过内购的需求,然后把整个过程记录下来,以防将来忘记之后回忆起来。

内购流程

在这里插入图片描述

内购代码逻辑

在这里插入图片描述

代码解析

下面的图片是整个苹果内购封装好的方法,可以直接拖过去用的,如果需要修改的就只有ValidationVoucherModel这个类,需要更改为对应公司的接口,里面的代码看多几篇就熟悉了。下面的图片里面,所有类的封装文件都是为IPAPurchase这个类服务的,再开发调用主要就是使用IPAPurchase就可以了
在这里插入图片描述
下面我会根据交易的整个流程解析代码的逻辑

启动监听

首先App启动的时候需要使用单例,初始化内购的监听方法,两个作用:1.每当app进行内购支付的时候,支付成功失败都会走代理的方法。2.app每次启动都回去调用该代理看看有没有没有走完内购的流程的订单。没有就会继续走一遍完成它

class AppDelegate: UIResponder, UIApplicationDelegate {var window: UIWindow?func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {//创建内购监听IPAPurchase.manager()?.startManager()return true}
}

结束监听

app回到后台就移除监听

func applicationDidEnterBackground(_ application: UIApplication) {IPAPurchase.manager()?.stopManager()
}

购买商品的方法

在商品购买的按键方法里面,通过单例直接调用购买的封装方法就可以了

IPAPurchase.manager()?.buyProduct(withProductID: "201912040101", currentBaseUrl: "http://192.168.1.20:8082/", currentAccountID: String(User.default.accountVO.id), currentOrderID: String(), currentVC: self, payResult: { (isSuccess, result, errorMsg) inprint("result = \(String(describing: result))")if isSuccess {print("购买成功")}else{print("购买失败 - \(String(describing: errorMsg))")}
})

接下来下面的代码解析就是根据把支付的方法一个一个点进去深入解析内购的流程,解析整个代码逻辑,拆解代码详细解析

发起购买的内部方法

#pragma mark -- 发起购买的方法
-(void)buyProductWithProductID:(NSString *)productID CurrentBaseUrl:(NSString *)baseUrl CurrentAccountID:(NSString *)accountID currentOrderID:(NSString *)orderID currentVC:(UIViewController *)vc payResult:(PayResult)payResult{//保存产品IDself.productId = productID;//保存baseUrlself.baseUrl = baseUrl;//保存用户IDself.accountID = accountID;//保存订单IDself.orderID = orderID;//保存当前控制器self.vc = vc;//结束上次未完成的交易[self removeAllUncompleteTransactionsBeforeNewPurchase];//绑定闭包self.payResultBlock = payResult;//提示框购买中//如果产品ID为空if (!self.productId.length) {//显示产品ID为空UIAlertController*alet=[UIAlertController alertControllerWithTitle:nil message:@"没有相应的产品" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction*sure=[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];[alet addAction:sure];[vc presentViewController:alet animated:YES completion:nil];}//检测是否允许内购if ([SKPaymentQueue canMakePayments]) {//向苹果发起内购产品列表[self requestProductInfo:self.productId];}else{//请打开应用程序付费购买功能UIAlertController*alet=[UIAlertController alertControllerWithTitle:nil message:@"请打开应用程序付费购买功能" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction*sure=[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];[alet addAction:sure];[vc presentViewController:alet animated:YES completion:nil];}}

检测未完成的订单

在购买之前,先看看有没有上一个没有完成的订单,如果有就结束上一次未完成的订单。

//结束上次未完成的交易
[self removeAllUncompleteTransactionsBeforeNewPurchase];#pragma mark -- 结束上次未完成的交易
-(void)removeAllUncompleteTransactionsBeforeNewPurchase{//查看数组中是否有未完成的订单NSArray* transactions = [SKPaymentQueue defaultQueue].transactions;if (transactions.count >= 1) {for (NSInteger count = transactions.count; count > 0; count--) {SKPaymentTransaction* transaction = [transactions objectAtIndex:count-1];if (transaction.transactionState == SKPaymentTransactionStatePurchased||transaction.transactionState == SKPaymentTransactionStateRestored) {[[SKPaymentQueue defaultQueue]finishTransaction:transaction];}}}else{NSLog(@"没有历史未消耗订单");}
}

检测是否允许内购

结束上一次未完成的订单后,检测是否允许内购,向苹果发起获取内购产品列表

//检测是否允许内购
if ([SKPaymentQueue canMakePayments]) {//向苹果发起内购产品列表[self requestProductInfo:self.productId];
}else{//请打开应用程序付费购买功能UIAlertController*alet=[UIAlertController alertControllerWithTitle:nil message:@"请打开应用程序付费购买功能" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction*sure=[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];[alet addAction:sure];[vc presentViewController:alet animated:YES completion:nil];
}

发起请求

获取代码的列表发送请求的详细代码就是主要是多请求对象准守一下代理

#pragma mark -- 发起购买请求   检索产品  去苹果开发网站查看这个商品是否存在  是否存在通过代理SKProductsRequestDelegate  返回结果
-(void)requestProductInfo:(NSString *)productID{NSArray * productArray = [[NSArray alloc]initWithObjects:productID,nil];NSSet * IDSet = [NSSet setWithArray:productArray];//把产品ID封装成一个SKProductsRequest请求对象request = [[SKProductsRequest alloc] initWithProductIdentifiers:IDSet];//对响应c方法request.delegate = self;//发送商品请求[request start];}

获取商品列表

发起请求之后,产品列表是通过代理的形式返回的,拿到商品id之后就发起支付

#pragma mark -- SKProductsRequestDelegate 查询成功后的回调
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{//把所有的产品检索回来NSArray *myProduct = response.products;    if (myProduct.count == 0) {//提示框,没有商品if (self.payResultBlock) {self.payResultBlock(NO, nil, @"无法获取产品信息,购买失败");}return;}//用于保存产品对象(其中产品ID就在里面)SKProduct * product = nil;//打印所有列表的相关信息for(SKProduct * pro in myProduct){NSLog(@"SKProduct 描述信息%@", [pro description]);NSLog(@"产品标题 %@" , pro.localizedTitle);NSLog(@"产品描述信息: %@" , pro.localizedDescription);NSLog(@"价格: %@" , pro.price);NSLog(@"Product id: %@" , pro.productIdentifier);if ([pro.productIdentifier isEqualToString:self.productId]) {product = pro;break;}}//如果产品不为空if (product) {//把产品添加到支付对象里面SKMutablePayment * payment = [SKMutablePayment paymentWithProduct:product];//使用苹果提供的属性,将平台订单号复制给这个属性作为透传参数payment.applicationUsername = self.orderID;//保存用户ID  目的是防止漏单后,用户登录App登录了别的用户,然后App有漏单,一启动走补单流程,就充错人[[NSUserDefaults standardUserDefaults] setObject:self.accountID forKey:@"unlock_iap_userId"];//调用购买产品接口  购买成功之后会去到updatedTransactions回调[[SKPaymentQueue defaultQueue] addPayment:payment];}else{NSLog(@"没有此商品信息");}
}

支付结果代理回调

支付成功失败都会通过代理的形式在枚举中反应。

#pragma mark -- 监听结果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{//当用户购买的操作有结果时,就会触发下面的回调函数,for (SKPaymentTransaction * transaction in transactions) {//根据返回的状态进行处理switch (transaction.transactionState) {//交易完成case SKPaymentTransactionStatePurchased:{[self completeTransaction:transaction];}break;//交易失败case SKPaymentTransactionStateFailed:{[self failedTransaction:transaction];}break;//已经购买过该商品case SKPaymentTransactionStateRestored:{[self restoreTransaction:transaction];}break;//正在购买中...case SKPaymentTransactionStatePurchasing:{NSLog(@"正在购买中...");//[[SKPaymentQueue defaultQueue]finishTransaction:transaction];(会蹦)}break;//最终状态未确定case SKPaymentTransactionStateDeferred:{NSLog(@"最终状态未确定");}break;default:break;}}
}

然后调用成交交易的方法

#pragma mark -- 交易完成的回调
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{//获取交易成功后的购买凭证[self getAndSaveReceipt:transaction];  
}

保存凭证,发送服务器验证

获取交易成功后的购买凭证
1.获取到凭证之后首先保存起来
2.使用后台提供的接口给后台去苹果服务器去进行验证

#pragma mark -- 获取购买凭证  并保存到Tmp文件里面去
-(void)getAndSaveReceipt:(SKPaymentTransaction *)transaction{//存储  向服务器验证凭证前的 凭证 订单号 用户ID 交易时间(简单:向服务器验证前保存一下)NSMutableDictionary *dict = [self saveServeCheskWithSaveReceipt:transaction];//向服务器发送订单ID 凭证验证  购买  然后发货,发货的动作其实就是服务器在订单的某一个属性里面修改状态。[self sendAppStoreRequestBuyWithReceipt:dict[@"receipt_key"] userId:dict[@"user_id"] paltFormOrder:dict[@"order"] trans:transaction];
}

下面的方法就是保存整个内购的过程

#pragma mark -- 存储  向服务器验证凭证前的 凭证 订单号 用户ID 交易时间(简单:向服务器验证前保存一下)
-(NSMutableDictionary *)saveServeCheskWithSaveReceipt:(SKPaymentTransaction *)transaction{//初始化字典NSMutableDictionary * dic = [[NSMutableDictionary alloc]init];//保存凭证到字典里面//获取交易凭证NSURL * receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];NSData * receiptData = [NSData dataWithContentsOfURL:receiptUrl];NSString * base64String = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];NSLog(@"base64String - %@",base64String);[dic setValue: base64String forKey:@"receipt_key"];//保存订单号到字典里面//透传参数  把刚刚购买前 transaction.payment.applicationUsername   里面存储的订单号那回来/*为什么不从上面的self.order获取你,如果这样获取就不会出现空的问题?这样想是错的。如果这样想的话,这个applicationUsername的参数就没有意义了。这个参数的设定是为了下面的坑而设定的。如果用户付款的之后,由于用户网络或者其他各种原因的问题,在没有拿到凭证之前(也就是没有进来updatedTransactions这个回调方法)把App退出。并且删了。这时候,用户重新下载App下.重新登录。由于订单没有结束(因为没有执行到)[[SKPaymentQueue defaultQueue]finishTransaction:transaction];这个方法。所以下次启动Appc注册监听之后,App马上会执行updatedTransactions的方法。方法的transaction对象会返回凭证给你,而applicationUsername属性里面存的就是你刚刚删除前的订单号。如果没有用applicationUsername设置对应凭证的订单号。就算给了凭证给你,你也不知道是哪张订单。到时候向公司服务器是验证不了的。*/NSString *order = @"";if (transaction.payment.applicationUsername != nil) {order = transaction.payment.applicationUsername;}else{order = self.orderID;}//如果这个返回为nilNSLog(@"后台订单号 -- %@",order);[dic setValue: order forKey:@"order"];//保存交易时间到字典里面[dic setValue:[self getCurrentZoneTime] forKey:@"time"];NSString * userId;//NSUserDefaults 值得注意的是对相同的key赋值约等于一次覆盖/*我觉得这里有问题。我决得。保存userID应该放在[[SKPaymentQueue defaultQueue] addPayment:payment];前面保存userid,你放在这里的话要订单凭证成功返回才保存,如果用户付钱后,拿到凭证前删除的话就GG了,反正NSUserDefaults是覆盖的形式的。这个问题有待验证。因为你不存不成功,杀死APP后下次进来就没有UserID了。为了确保成功。应该在用户付钱前就要保存*///  //下面userid不为0的情况是用户成功交易,一直留在app才能走到这里,这时候就拿上保存用户ID。
//  if (self.accountID) {//如果用户ID不为空
//    userId = self.accountID;
//    //把用户ID存起来
//    [[NSUserDefaults standardUserDefaults] setObject:userId forKey:@"unlock_iap_userId"];
//  }else{//如果用户ID为空  用户进来userid为空的原因是,用户交易未完成的情况下,下次重新打开App上会执行updatedTransactions的方法。这时候userid未空的。为空的话就拿会App关掉前保存的userid
//    //从沙盒中获取用户ID
//    userId = [[NSUserDefaults standardUserDefaults] objectForKey:@"unlock_iap_userId"];
//  }//从沙盒中获取用户IDuserId = [[NSUserDefaults standardUserDefaults] objectForKey:@"unlock_iap_userId"];//保存用户ID到字典里面[dic setValue: userId forKey:@"user_id"];//命名plist文件 生成唯一的字符串NSString *fileName = [NSString UUID];//沙盒Tmp 保存方式NSString *savedPath = [NSString stringWithFormat:@"%@/%@.plist", [SandBoxHelper iapReceiptPath], fileName];//这个存储成功与否其实无关紧要BOOL ifWriteSuccess = [dic writeToFile:savedPath atomically:YES];if (ifWriteSuccess){NSLog(@"购买凭据存储成功!");}else{NSLog(@"购买凭据存储失败");}return dic;}

使用后台提供的接口给后台去苹果服务器去进行验证

#pragma mark -- 去服务器验证购买
-(void)sendAppStoreRequestBuyWithReceipt:(NSString *)receipt userId:(NSString *)userId paltFormOrder:(NSString * )order trans:(SKPaymentTransaction *)transaction{ValidationVoucherModel *model = [[ValidationVoucherModel alloc] init];[model getValidationVoucherRequestCurrentBaseUrl:self.baseUrl CurrentAccountID:userId currentOrderID:order currentReceipt:receipt DataSuccess:^(id _Nullable result) {NSLog(@"result - %@",result);BOOL changeOrder = result[@"data"][@"changeOrder"];if (changeOrder  == YES) {//删除  向服务器验证凭证后的 凭证 订单号 用户ID 交易时间(简单:验证成功后可以把凭证删除)[self delectedConsumptionOfGoodsWithReceipt:receipt];//存储  向服务器验证凭证前的 凭证 订单号 用户ID 交易时间(简单:向服务器验证前保存一下)[self saveServeCheskWithSaveReceipt:transaction];self.payResultBlock(YES, @"已经发货", @"");//结束订单[[SKPaymentQueue defaultQueue]finishTransaction:transaction];}else{NSLog(@"未发货");}} failedBlock:^(NSError * _Nonnull error) {NSLog(@"error - %@",error);}];}

删除本地凭证

#pragma mark -- 删除  向服务器验证凭证后的 凭证 订单号 用户ID 交易时间(简单:验证成功后可以把凭证删除)
-(void)delectedConsumptionOfGoodsWithReceipt:(NSString * )receipt{NSFileManager *fileManager = [NSFileManager defaultManager];NSError * error;if ([fileManager fileExistsAtPath:[SandBoxHelper iapReceiptPath]]) {NSArray * cacheFileNameArray = [fileManager contentsOfDirectoryAtPath:[SandBoxHelper iapReceiptPath] error:&error];if (error == nil) {for (NSString * name in cacheFileNameArray) {NSString * filePath = [NSString stringWithFormat:@"%@/%@", [SandBoxHelper iapReceiptPath], name];NSFileManager *fileManager = [NSFileManager defaultManager];NSError * error;NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];NSString * localReceipt = [dic objectForKey:@"receipt_key"];//通过凭证进行对比if ([receipt isEqualToString:localReceipt]) {BOOL ifRemove = [fileManager removeItemAtPath:filePath error:&error];if (ifRemove) {NSLog(@"验证凭证成功后 移除成功");}else{NSLog(@"验证凭证成功后 移除失败");}}else{NSLog(@"本地无与之匹配的订单");}}}}
}

结束交易(关键代码)

//结束订单
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];

经验

1.关于支付丢单的问题

问题1:账号A: 订单A;支付成功了(拿到凭证),应该拿着(凭证,账号id,订单号)上存到后台验证,这个时候把App退出,重新启动,账号A登录,但是这个时候 订单A丢失了缓存没了,如何解决该丢单的问题。

解答:支付是可以把订单保存到payment.applicationUsername = self.orderID;的属性中,登录原来的账号,在未完成支付(即调用:[[SKPaymentQueue defaultQueue]finishTransaction:transaction];支付会仍然继续拿到刚支付的凭证)原来的账号,原来的订单id,原来的凭证就可以继续上存后台验证登录。
其实可以把订单id做一个本地保存,安全一定,防止payment.applicationUsername = self.orderID;获取回来的订单id为空。

问题2:账号A: 订单A;支付成功了(拿到凭证),应该拿着(凭证,账号id,订单号)上存到后台验证,这个时候把App删除,重新下载,账号A登录,但是这个时候 订单A丢失了(即使保存在本地,app删除也会把订单号删除),如何解决该丢单的问题

解答:支付是可以把订单保存到payment.applicationUsername = self.orderID;的属性中,登录原来的账号,在未完成支付(即调用:[[SKPaymentQueue defaultQueue]finishTransaction:transaction];支付会仍然继续拿到刚支付的凭证)原来的账号,原来的订单id,原来的凭证就可以继续上存后台验证登录。

问题3:账号A: 订单A;支付成功了(拿到凭证),应该拿着(凭证,账号id,订单号)上存到后台验证,这个时候把App退出,重新启动,账号B登录,但是这个时候刚刚账号A付款会变成账号B吗,上存后台服务器成功后

解答:会

问题3:账号A: 订单A;支付成功了(拿到凭证),应该拿着(凭证,账号id,订单号)上存到后台验证,这个时候把App退出,换另一台手机登录账号A,账号A还能够继续完成支付吗?

解答: 我没有似过,分两种情况:如果把之前的手机苹果id退出,在另一台手机登录苹果id,app登录账号A,如果能拿到凭证就能继续完成支付,如果手机苹果id登录拿不到凭证就无法继续完成支付。

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

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

相关文章

Linux文件和文件夹操作

一、文件操作 功能项命令实例作用文件创建vi /opt/learn/hello.txt 在目录/opt/learn下创建文件hello.txt并进入vi编辑界面 touch /opt/learn/test在目录/opt/learn下创建空白文件testcat > /opt/catfile创建文件catfile并在屏幕上输入内容&#xff0c;最后按 Ctrl D 退出…

【学习心得】神经网络知识中的符号解释

这里我对我学到的神经网络知识中&#xff0c;常见的符号做一下记录和总结&#xff0c;方便自己在后面学习中复习。下图二分类识别图像识别猫为例。为了保存一张图片&#xff0c;需要三个矩阵&#xff0c;它们分别对应图片中的红、绿、蓝三种颜色通道&#xff0c;如果图片大小为…

Django路由

Router介绍 在实际开发过程中&#xff0c;一个Django项目会包含很多的app,这时候如果我们只在主路由里进行配置就会显得杂乱无章&#xff0c;所以通常会在每个app里&#xff0c;创建各自的urls.py路由模块&#xff0c;然后从根路由出发&#xff0c;将app所属的url请求&#xff…

类与对象上C++

文章目录 一、1.面向过程和面向对象初步认识二、类的定义1.类的两种定义方式 三、类的访问限定符及封装1.访问限定符2.面试题3.封装 四、类对象模型1. 类对象的存储方式猜测2. 结构体内存对齐规则 五、this指针1.this指针的引出2.this指针的特性 六、 C语言和C实现Stack的对比 …

如何快速进行城市内涝模拟?HTWATER软件

原文链接&#xff1a;如何快速进行城市内涝模拟&#xff1f;HTWATER软件https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247599079&idx2&sndc6f3da8b17c5587cf5b7766e7019729&chksmfa820200cdf58b16658983ecfbf2b369bff39813302942d6f7eb7b71428c68da71…

在Windows上交叉编译STM32(环境搭建)

在Windows上交叉编译STM32 Keil 虽然好用&#xff0c;但是是收费的&#xff0c;不想破解怎么办~ 使用交叉编译工具&#xff01; 交叉编译工具下载 官方交叉编译工具下载连接 下载解压好后将 bin 目录写入 PATH&#xff0c; 使用命令行检测是否安装成功。 Windows 安装 make …

未解决的问题:使用fgets循环读取字符串总是少一行

一、使用fgets循环读取字符串总是少一行 代码 #include<stdio.h> int main() {int n, i;scanf("%d", &n);char line[n][1000];for (i 0; i < n; i) {fgets(line[i], 1000, stdin);}for (i 0; i < n; i) {printf("%s", line[i]);}retur…

纳斯达克大屏媒体尺寸与投放费用:一次投放需要多少钱?

纳斯达克大屏媒体尺寸与投放费用&#xff1a;一次投放需要多少钱&#xff1f; 1. 纳斯达克图片要求 1.1 像素要求 高度&#xff1a;2336 像素宽度&#xff1a;1832 像素 1.2 分辨率要求 像素比率&#xff1a;1.0 px 72 dpi 1.3 文件格式要求 静态图片格式&#xff1a;.…

Django 仿博客园练习

数据库搭建 部分功能介绍 【一】注册 &#xff08;1&#xff09;效果显示、简单简介 主要亮点 结合了layui和forms组件默认头像可以随着性别的选择发生改变自定义头像可以实时更新显示forms组件报错信息可以局部刷新显示在对应框体下面 没有直接使用layui的前端验证后端验证…

unity中手势识别开源代码——HandPoseBarracuda

HandPoseBarracuda是一个使用单目彩色摄像头工作的神经网络手/手指追踪器的概念验证实现。 基本上,HandPoseBarracuda是MediaPipe Hands管道的一个部分端口。尽管它并不是原始包的直接端口,但它使用了相同的基本设计和相同的预训练模型。 请注意,这只是一个概念验证实现。…

SQLite数据库成为内存中数据库(三)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite使用的临时文件&#xff08;二&#xff09; 下一篇&#xff1a;SQLite中的原子提交&#xff08;四) ​​ SQLite数据库通常存储在单个普通磁盘中文件。但是&#xff0c;在某些情况下&#xff0c;数据库可能…

Dockerfile和Docker-compose

一、概述 Dockerfile和Docker Compose是用于构建和管理 Docker 容器的两个工具&#xff0c;但它们的作用和使用方式不同。 Dockerfile Dockerfile 是一个文本文件&#xff0c;用于定义 Docker 镜像的构建规则。它包含一系列指令&#xff0c;如 FROM&#xff08;指定基础镜像…

excel统计分析——协方差分析基本原理

参考资料&#xff1a;生物统计学 方差分析中&#xff0c;要求除试验因素外的其他条件保持在相同水平上才能对实验结果的差异显著性进行比较&#xff0c;然而有些非试验因素很难或不可能人为控制&#xff0c;此时如果使用方差分析法推断处理其差异显著性&#xff0c;往往会导致错…

Linux进程的管理和进程的状态

进程的基本概念&#xff1a; 程序的一个执行实例 &#xff0c;正在执行的程序等等 ——— 课本概念 担当分配系统资源的实体&#xff0c;例如cpu时间&#xff0c;内存 -----内核的观点 一、进程的管理 processbar 存储在磁盘中的可执行文件 可执行文件在启动/运行的同时&…

阿里云安全产品简介,Web应用防火墙与云防火墙产品各自作用介绍

在阿里云的安全类云产品中&#xff0c;Web应用防火墙与云防火墙是用户比较关注的安全类云产品&#xff0c;二则在作用上并不是完全一样的&#xff0c;Web应用防火墙是一款网站Web应用安全的防护产品&#xff0c;云防火墙是一款公共云环境下的SaaS化防火墙&#xff0c;本文为大家…

政安晨:【Keras机器学习实践要点】(四)—— 顺序模型

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 介绍 Keras是一个用于构建和训练深度学习模…

MySQL数据库高级语句(一)

文章目录 MySQL高级语句older by 排序区间判断查询或与且&#xff08;or 与and&#xff09;嵌套查询&#xff08;多条件&#xff09;查询不重复记录distinctcount 计数限制结果条目limit别名as常用通配符 结语 MySQL高级语句 1构建测试用表 create table test1 (id int prima…

湖北汽车工业学院 实验一 关系数据库标准语言SQL

头歌 实验一 关系数据库标准语言SQL 制作不易&#xff01;点个关注呗&#xff01;为大家创造更多的价值&#xff01; 目录 头歌 实验一 关系数据库标准语言SQL**制作不易&#xff01;点个关注呗&#xff01;为大家创造更多的价值&#xff01;** 第一关&#xff1a;创建数据库第…

Apple Vision Pro应用合集

这里给大家分享一个网站&#xff0c;手机了最新的apple vision pro 上面运行的应用。 1、查找应用&#xff1a;用户可以浏览特色推荐的应用&#xff0c;或者通过随机挑选功能发现新的应用。 2、社区交流&#xff1a;提供社区功能&#xff0c;用户可以在这里交流使用体验、分享…

小程序接入第三方信息流流程 下载SDK

由第三方信息流提供相应的SDK下载链接以及接入说明和开发文档或其他方式接入&#xff0c;如果第三方能支持小程序SDK&#xff0c;则不需要后面步骤&#xff0c;只需要提供相关开发文档和接入方式接口 接入SDK 后台开发人员接入第三方提供的SDK&#xff0c;并进行相关接口开发…