当前位置: 首页 > news >正文

ios swift开发--ios远程推送通知配置


远程推送通知(Push Notifications)在 iOS 平台上是免费提供的,但需要一些准备工作。以下是开通和使用远程推送通知的基本步骤:

开通远程推送通知

注册 Apple Developer Program:
访问 Apple Developer 并注册一个开发者账号。个人开发者账号是免费的,但如果你想发布应用到 App Store,需要支付 99 美元/年的费用。
创建和配置 App ID:
登录 Apple Developer 账号,进入 Certificates, Identifiers & Profiles。
创建一个新的 App ID,并启用“Push Notifications”服务。
创建和下载推送证书:
在同一页面中,创建一个新的推送证书(Push Notification SSL Certificate)。
下载并安装证书,以便在你的服务器上使用。
配置 APNs 证书:
将下载的推送证书导出为 .p12 文件。
将 .p12 文件转换为 .pem 文件(可选,取决于你的服务器需求)。
在 Xcode 中配置项目:
打开你的 Xcode 项目。
选择项目的 Target,进入“Signing & Capabilities”选项卡。
添加“Push Notifications”功能。
确保你的 App ID 和 Team 都正确配置。
代码示例

以下是一个简单的示例,展示如何在 iOS 应用中注册和接收远程推送通知:

请求推送通知权限

import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 请求推送通知权限
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                print("通知权限已授予")
            } else {
                print("通知权限被拒绝")
            }
        }

        // 注册推送通知
        application.registerForRemoteNotifications()

        return true
    }

    // 处理远程推送通知的注册
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
        let token = tokenParts.joined()
        print("Device Token: \(token)")

        // 将设备令牌发送到你的服务器
        sendDeviceTokenToServer(deviceToken: token)
    }

    // 处理远程推送通知的注册失败
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: \(error.localizedDescription)")
    }

    // 发送设备令牌到服务器
    func sendDeviceTokenToServer(deviceToken: String) {
        // 你的服务器端逻辑
        print("Sending device token to server: \(deviceToken)")
    }
}
接收推送通知

Swift
浅色版本

import UserNotifications

@main
struct YourApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 请求推送通知权限
        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                print("通知权限已授予")
            } else {
                print("通知权限被拒绝")
            }
        }

        // 注册推送通知
        application.registerForRemoteNotifications()

        return true
    }

    // 处理远程推送通知的注册
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
        let token = tokenParts.joined()
        print("Device Token: \(token)")

        // 将设备令牌发送到你的服务器
        sendDeviceTokenToServer(deviceToken: token)
    }

    // 处理远程推送通知的注册失败
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: \(error.localizedDescription)")
    }

    // 发送设备令牌到服务器
    func sendDeviceTokenToServer(deviceToken: String) {
        // 你的服务器端逻辑
        print("Sending device token to server: \(deviceToken)")
    }

    // 处理接收到的推送通知
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        // 处理用户点击通知后的操作
        print("Notification received: \(response.notification.request.content.body)")
        completionHandler()
    }
}
服务器端

你需要一个服务器来发送推送通知。可以使用 Apple 的 APNs (Apple Push Notification service)。以下是一个简单的 Node.js 示例,展示如何使用 apn 库发送推送通知:

const apn = require('apn');

// 创建 APNs 连接
const options = {
    token: {
        key: './path/to/your/key.p8', // APNs auth key
        keyId: 'YOUR_KEY_ID', // The Key ID obtained from your developer account
        teamId: 'YOUR_TEAM_ID' // The Team ID obtained from your developer account
    },
    production: false // Set to true if sending notifications to production devices
};

const apnProvider = new apn.Provider(options);

// 创建通知
const note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expiry time (seconds from now)
note.badge = 1;
note.sound = "default";
note.alert = "This is a test notification!";
note.topic = 'com.yourcompany.yourapp'; // Bundle identifier of your app

// 发送通知
const deviceToken = 'YOUR_DEVICE_TOKEN';
apnProvider.send(note, deviceToken).then((result) => {
    console.log(result);
});
总结

注册 Apple Developer Program:免费注册,但发布应用到 App Store 需要付费。
配置 App ID 和推送证书:在 Apple Developer 账户中完成。
在 Xcode 中配置项目:添加“Push Notifications”功能。
请求和处理推送通知:在应用中请求权限并处理通知。
服务器端:使用 APNs 发送推送通知。
 

配置服务器端

发送远程推送通知(APNs)涉及几个步骤。

以下是一个详细的指南,使用 Node.js 作为示例语言,展示如何配置服务器端来发送推送通知。

步骤 1:准备 APNs 证书

创建 APNs 证书:
登录 Apple Developer 账户。
前往 Certificates, Identifiers & Profiles。
选择 Keys,然后点击 + 按钮创建一个新的密钥。
选择 Apple Push Notifications service (APNs),然后点击 Continue。
输入密钥的描述,然后点击 Generate。
下载生成的 .p8 文件并保存。
获取 Key ID 和 Team ID:
Key ID:在密钥列表中,找到你刚刚创建的密钥,复制其 Key ID。
Team ID:在 Apple Developer 账户的概览页面中,找到你的 Team ID。
步骤 2:安装 Node.js 和依赖

安装 Node.js:
如果你还没有安装 Node.js,可以从 Node.js 官网 下载并安装。
创建项目目录:
Sh
浅色版本

mkdir apns-server
cd apns-server
初始化项目:
Sh
浅色版本

npm init -y
安装 apn 库:
Sh
浅色版本

npm install apn
步骤 3:编写服务器代码

创建 index.js 文件:
Sh
浅色版本

touch index.js
编写代码:
Javascript
浅色版本

const apn = require('apn');

// APNs 连接配置
const options = {
    token: {
        key: './path/to/your/AuthKey_YourKeyID.p8', // APNs auth key path
        keyId: 'YOUR_KEY_ID', // The Key ID obtained from your developer account
        teamId: 'YOUR_TEAM_ID' // The Team ID obtained from your developer account
    },
    production: false // Set to true if sending notifications to production devices
};

// 创建 APNs 提供者
const apnProvider = new apn.Provider(options);

// 创建通知
const note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expiry time (seconds from now)
note.badge = 1;
note.sound = "default";
note.alert = "This is a test notification!";
note.topic = 'com.yourcompany.yourapp'; // Bundle identifier of your app

// 设备令牌
const deviceToken = 'YOUR_DEVICE_TOKEN';

// 发送通知
apnProvider.send(note, deviceToken).then((result) => {
    console.log("Notification sent:", result);
}).catch((error) => {
    console.error("Error sending notification:", error);
});
步骤 4:运行服务器

确保 AuthKey_YourKeyID.p8 文件路径正确:
将 ./path/to/your/AuthKey_YourKeyID.p8 替换为实际的文件路径。
运行服务器:
Sh
浅色版本

node index.js
步骤 5:测试推送通知

确保设备已注册推送通知:
在你的 iOS 应用中,确保设备已注册并获取到设备令牌。
运行服务器:
运行 node index.js,你应该会看到类似以下的输出:
浅色版本

Notification sent: { sent: [ 'YOUR_DEVICE_TOKEN' ], failed: [] }
检查设备:
检查你的设备是否收到了推送通知。
常见问题

设备未收到通知:
确保设备已正确注册推送通知。
确保设备令牌正确无误。
确保 APNs 证书和配置正确。
确保设备连接到互联网。
错误信息:
查看 console.error 输出的错误信息,根据错误信息进行调试。
进一步扩展

批量发送通知:
可以将多个设备令牌放入数组中,一次性发送通知。
Javascript
浅色版本

const deviceTokens = ['TOKEN1', 'TOKEN2', 'TOKEN3'];
apnProvider.send(note, deviceTokens).then((result) => {
    console.log("Notification sent:", result);
}).catch((error) => {
    console.error("Error sending notification:", error);
});
自定义通知内容:
可以在 note 对象中添加更多自定义字段,如 payload、customData 等。
 

//

这个通知的作用是开发者向所有用户发通知吗,什么情况下需要用到远程通知
远程推送通知(Remote Push Notifications)的主要作用是让开发者能够从服务器向用户的设备发送消息,即使应用不在前台运行或甚至被关闭。这种机制使得开发者可以在特定情况下及时通知用户,提高应用的活跃度和用户体验。

远程推送通知的主要用途

即时消息:
例如,在即时通讯应用中,当用户收到新消息时,可以通过推送通知提醒用户。
新闻更新:
新闻应用可以推送最新的新闻标题和摘要,吸引用户查看详细内容。
促销活动:
电商应用可以推送限时折扣、新品上市等信息,促进用户购买。
账户通知:
例如,银行应用可以推送账户余额变动、交易确认等重要信息。
事件提醒:
日历应用可以推送即将到来的会议或日程安排。
游戏更新:
游戏应用可以推送新的关卡、活动或排行榜变化。
安全通知:
安全应用可以推送异常登录、账户风险等信息。
什么情况下需要用到远程通知

用户互动:
当需要与用户进行实时互动时,例如社交应用中的新消息提醒。
重要信息传递:
当有重要信息需要立即告知用户时,例如账户安全、紧急通知等。
增加用户粘性:
通过定期推送有价值的内容,增加用户打开应用的频率,提高用户粘性。
数据同步:
当应用需要在后台同步数据时,可以通过推送通知触发应用进行数据同步。
用户召回:
通过推送通知召回长时间未使用应用的用户,提高用户活跃度。
示例场景

即时通讯应用:
用户 A 向用户 B 发送了一条消息,服务器检测到新消息后,向用户 B 的设备发送推送通知,提醒用户 B 有新消息。
新闻应用:
服务器检测到最新新闻更新,向订阅该类别的用户发送推送通知,提醒用户查看最新新闻。
电商应用:
服务器检测到限时折扣活动开始,向符合条件的用户发送推送通知,提醒用户参与活动。
银行应用:
用户进行一笔大额转账,服务器检测到交易后,向用户发送推送通知,确认交易详情。
实现步骤总结

设备注册推送通知:
应用请求设备注册推送通知,并获取设备令牌。
应用将设备令牌发送到服务器。
服务器发送推送通知:
服务器使用设备令牌和 APNs 证书向 APNs 发送通知。
APNs 将通知推送到设备。
示例代码回顾

客户端(iOS 应用)

import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 请求推送通知权限
        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                print("通知权限已授予")
            } else {
                print("通知权限被拒绝")
            }
        }

        // 注册推送通知
        application.registerForRemoteNotifications()

        return true
    }

    // 处理远程推送通知的注册
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
        let token = tokenParts.joined()
        print("Device Token: \(token)")

        // 将设备令牌发送到你的服务器
        sendDeviceTokenToServer(deviceToken: token)
    }

    // 处理远程推送通知的注册失败
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: \(error.localizedDescription)")
    }

    // 发送设备令牌到服务器
    func sendDeviceTokenToServer(deviceToken: String) {
        // 你的服务器端逻辑
        print("Sending device token to server: \(deviceToken)")
        // 例如,使用网络请求将设备令牌发送到服务器
        // URLSession 或其他网络库
    }

    // 处理接收到的推送通知
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        // 处理用户点击通知后的操作
        print("Notification received: \(response.notification.request.content.body)")
        completionHandler()
    }
}
服务器端(Node.js)

const apn = require('apn');

// APNs 连接配置
const options = {
    token: {
        key: './path/to/your/AuthKey_YourKeyID.p8', // APNs auth key path
        keyId: 'YOUR_KEY_ID', // The Key ID obtained from your developer account
        teamId: 'YOUR_TEAM_ID' // The Team ID obtained from your developer account
    },
    production: false // Set to true if sending notifications to production devices
};

// 创建 APNs 提供者
const apnProvider = new apn.Provider(options);

// 创建通知
const note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expiry time (seconds from now)
note.badge = 1;
note.sound = "default";
note.alert = "This is a test notification!";
note.topic = 'com.yourcompany.yourapp'; // Bundle identifier of your app

// 设备令牌
const deviceToken = 'YOUR_DEVICE_TOKEN';

// 发送通知
apnProvider.send(note, deviceToken).then((result) => {
    console.log("Notification sent:", result);
}).catch((error) => {
    console.error("Error sending notification:", error);
});


总结

远程推送通知是一种强大的工具,可以帮助开发者与用户保持实时互动,提高应用的活跃度和用户体验。通过上述步骤,你可以实现从服务器向用户设备发送推送通知的功能。

相关文章:

ios swift开发--ios远程推送通知配置

远程推送通知(Push Notifications)在 iOS 平台上是免费提供的,但需要一些准备工作。以下是开通和使用远程推送通知的基本步骤: 开通远程推送通知 注册 Apple Developer Program: 访问 Apple Developer 并注册一个开发…...

【JavaEE进阶】CSS

本节⽬标 掌握 CSS 基本语法规范和CSS选择器的各种⽤法, 熟练使⽤CSS的常⽤属性. 一.CSS介绍 1.什么是CSS? CSS(Cascading Style Sheet),层叠样式表, ⽤于控制⻚⾯的样式. CSS 能够对⽹⻚中元素位置的排版进⾏像素级精确控制, 实现美化⻚⾯的效果. 能够做到⻚⾯…...

基于Java Springboot宠物领养救助平台

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…...

C/C++ 中有哪些类型转换方式? 分别有什么区别?

在C编写C/C代码的时候,我们经常会遇到发生类型转换的场景,比如 赋值运算符的两个操作数不同、实参和形参类型不同、函数返回值类型和接收返回值的类型不同,都会发生类型转换;所以,在C语言中提供了两种类型转换 —— 隐…...

小程序租赁系统开发为企业提供高效便捷的租赁服务解决方案

内容概要 在这个数字化飞速发展的时代,小程序租赁系统应运而生,成为企业管理租赁业务的一种新选择。随着移动互联网的普及,越来越多的企业开始关注如何利用小程序来提高租赁服务的效率和便捷性。小程序不仅可以为用户提供一个快速、易用的平…...

Scala的Array

数组:物理空间上连续的(一个挨一个) 优势:根据下标,能快速找到元素 列表:物理空间上不连续(不是一个元素挨着一个元素) 优势:插入元素,删除比较快 object…...

等保测评怎么做?具体流程是什么?

等保测评是对信息系统进行等保(等级保护)安全评测的过程。等保是指对信息系统进行等级化保护管理,目的是提高信息系统的安全性,防止信息泄露、篡改、破坏等安全问题。哈尔滨等保测评按照《中华人民共和国网络安全法》及《信息安全…...

基于YOLOv8深度学习的汽车车身车损检测系统研究与实现(PyQt5界面+数据集+训练代码)

本文研究并实现了一种基于YOLOV8深度学习模型的汽车车身车损检测系统,旨在解决传统车损检测中效率低、精度不高的问题。该系统利用YOLOV8的目标检测能力,在单张图像上实现了车身损坏区域的精确识别和分类,尤其是在车身凹痕、车身裂纹和车身划…...

力扣 LeetCode 144. 二叉树的前序遍历(Day6:二叉树)

解题思路&#xff1a; 方法一&#xff1a;递归&#xff08;中左右&#xff09; class Solution {List<Integer> res new ArrayList<>();public List<Integer> preorderTraversal(TreeNode root) {recur(root);return res;}public void recur(TreeNode roo…...

Adobe Illustrator(Ai)修图软件入门操作参考,收集查过的各个细节用法

到现在&#xff0c;对于Ai的使用也是一半一半&#xff0c;基本上都是用到啥就查啥。因为用得也不是很频繁&#xff0c;脑子也记不住很多操作&#xff0c;所以有时候靠肌肉记忆&#xff0c;很多时候&#xff0c;得再百度一遍…… 所以 我在这再备份一下&#xff0c;做个搬运工 …...

Apache Paimon、Apache Hudi、Apache Iceberg对比分析

Apache Paimon、Apache Hudi、Apache Iceberg 都是面向大数据湖的表格式存储管理框架。它们各自的架构、数据管理方式以及适用场景有所不同。下面是对三者的详细对比分析: 1. 基本简介 Apache Paimon: Paimon 是一个新兴的数据湖存储引擎,旨在支持流批一体的数据处理和管理…...

[ 网络安全介绍 5 ] 为什么要学习网络安全?

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…...

生产环境centos8 Red Hat8部署ansible and 一键部署mysql两主两从ansible脚本预告

一、各节点服务器创建lvm逻辑卷组 1.初始化磁盘为物理卷&#xff08;PV&#xff09; 命令&#xff1a;sudo pvcreate /dev/vdb 2.创建卷组&#xff08;VG&#xff09; 命令&#xff1a;sudo vgcreate db_vg /dev/vdb 3.创建逻辑卷&#xff08;LV&#xff09; 命令&#xff1a;s…...

华为云stack网络服务流量走向

1.同VPC同子网同主机内ECS间互访流量走向 一句话通过主机内部br-int通信 2.同VPC同子网跨主机ECS间互访流量走向 3.同VPC不同子网同主机ECS间互访流量走向 查看ECS配置文件底层KVM技术 查看日志 查看ECS的ID号&#xff08;管理员身份查询所有租户信息&#xff09; 查看ECS的其…...

嵌入式硬件杂谈(二)-芯片输入接入0.1uf电容的本质(退耦电容)

引言&#xff1a;对于嵌入式硬件这个庞大的知识体系而言&#xff0c;太多离散的知识点很容易疏漏&#xff0c;因此对于这些容易忘记甚至不明白的知识点做成一个梳理&#xff0c;供大家参考以及学习&#xff0c;本文主要针对芯片输入接入0.1uf电容的本质的知识点的进行学习。 目…...

计算机网络HTTP——针对实习面试

目录 计算机网络HTTP什么是HTTP&#xff1f;HTTP和HTTPS有什么区别&#xff1f;分别说明HTTP/1.0、HTTP/2.0、HTTP/3.0请说明访问网页的全过程请说明HTTP常见的状态码Cookie和Session有什么区别&#xff1f;HTTP请求方式有哪些&#xff1f;请解释GET和POST的区别&#xff1f;HT…...

JAVA中对象实体与对象引用有何不同?举例说明

在 Java 中&#xff0c;对象实体&#xff08;Object instance&#xff09;和对象引用&#xff08;Object reference&#xff09;是两个不同的概念&#xff0c;虽然它们通常被一起讨论&#xff0c;但它们的作用和表现方式是不同的。下面我们来详细说明这两者的区别。 1. 对象实体…...

C++设计思想-001-设计模式-单例模式

1.单例模式优点 保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享; 实现: 1.1 单例模式的类只提供私有的构造函数 1.2类定义中含有一个该类的静态私有对象 1.3该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象 2.单…...

远程连接服务器

1、远程连接服务器简介 ssh secure shell 非对称加密&#xff1a;一对公钥私钥 对称加密&#xff1a;加密和解密使用的是同一把密钥&#xff1b;(同一秘钥既可以进行加密也可以进行解密 )优势&#xff1a;使用一个秘钥它的加密效率高一些&#xff08;快一些&#xff09; …...

【分布式技术】ES扩展知识-Elasticsearch分词器的知识与选择

ES知识扩展 分词器有哪些&#xff1f;1. 标准分词器&#xff08;Standard Analyzer&#xff09;&#xff1a;示例示例文本分析配置参数与自定义应用场景 2. Simple Analyzer&#xff1a;示例示例文本分析应用场景与限制结论 3. Whitespace Analyzer&#xff1a;示例示例文本分析…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...