【愚公系列】《移动端AI应用开发》029-iOS端应用开发(数据存储与本地缓存)

💎【行业认证·权威头衔】

✔ 华为云天团核心成员:特约编辑/云享专家/开发者专家/产品云测专家

✔ 开发者社区全满贯:CSDN博客&商业化双料专家/阿里云签约作者/腾讯云内容共创官/掘金&亚马逊&51CTO顶级博主

✔ 技术生态共建先锋:横跨鸿蒙、云计算、AI等前沿领域的技术布道者

🏆【荣誉殿堂】

🎖 连续三年蝉联"华为云十佳博主"(2022-2024)

🎖 双冠加冕CSDN"年度博客之星TOP2"(2022&2023)

🎖 十余个技术社区年度杰出贡献奖得主

📚【知识宝库】

覆盖全栈技术矩阵:

◾ 编程语言:.NET/Java/Python/Go/Node...

◾ 移动生态:HarmonyOS/iOS/Android/小程序

◾ 前沿领域:物联网/网络安全/大数据/AI/元宇宙

◾ 游戏开发:Unity3D引擎深度解析

文章目录

  • 🚀前言
  • 🚀一、数据存储与本地缓存
    • [🔎6.4.1 CoreData 与 SQLite 存储](#🔎6.4.1 CoreData 与 SQLite 存储)
    • [🔎6.4.2 文件管理与 UserDefaults](#🔎6.4.2 文件管理与 UserDefaults)
    • [🔎6.4.3 内存缓存与NSCache](#🔎6.4.3 内存缓存与NSCache)

🚀前言

本章深入探讨了iOS端应用开发的关键技术与实现方法,重点介绍了如何将DeepSeek 的强大AI能力集成到iOS应用中。通过详细的步骤和代码示例,本章阐明了如何在iOS平台上配置和使用DeepSeekSDK,如何与后端进行高效的数据交互,以及如何处理多种AI任务。结合iOS平台的开发特点,优化了性能、网络请求和用户体验,使得AI应用能够在iOS设备上高效、稳定地运行。

🚀一、数据存储与本地缓存

本节详细阐述了iOS中常用的存储方式,如UserDefaults、CoreData、SQLite以及文件系统操作。还特别讨论了如何利用本地缓存技术提升应用性能,减少不必要的网络请求,并优化用户体验。通过对数据持久化的深度解析,本节为开发者提供了在iOS平台上高效存储和缓存数据的实用方法。

🔎6.4.1 CoreData 与 SQLite 存储

在现代移动应用开发中,持久化存储是一个关键功能,它允许应用在关闭或重启后保存和恢复数据。iOS提供了几种存储数据的方式,其中CoreData和SQLite是两种非常常见的选择。它们各自有其特点和应用场景,但都能够提供高效、持久的存储解决方案。CoreData是苹果提供的一个框架,它允许开发者以对象的形式操作数据库,并通过对象模型来管理数据。CoreData不仅可以轻松地处理对象间的关系,还提供了内存管理、对象版本控制、以及与数据库的无缝集成。CoreData通过内部封装了SQLite来提供持久化存储,因此可以通过CoreData处理SQLite数据库的操作,但提供了更高层次的抽象。

SQLite是一个轻量级的关系型数据库,它是跨平台的,并且是应用中常用的数据存储方式。SQLite为iOS开发者提供了直接访问数据库文件的能力,通过SQL查询语言来操作数据。相比CoreData,SQLite提供了更细粒度的控制,但需要更多的手动管理工作。

在本小节中,我们将结合使用CoreData和SQLite来展示如何在iOS中实现数据存储功能,尤其是在需要高效存储与检索的AI应用中,如何利用这两种存储方式来存储用户数据、历史记录以及DeepSeek的API返回的数据。

【例6-8】 展示如何在iOS应用中结合使用CoreData与SQLite来存储从DeepSeek API返回的数据。我们通过CoreData进行数据持久化,同时使用SQLite作为底层存储。该示例包括以下几个步骤:

  1. 定义数据模型。
  2. 创建CoreData模型并配置SQLite存储。
  3. 通过DeepSeek API获取数据并保存到数据库中。
swift 复制代码
import UIKit
import CoreData

// 定义数据模型Post
struct Post: Codable {
    let userId: Int
    let id: Int
    let title: String
    let body: String
}

class ViewController: UIViewController {
    var dataLabel: UILabel!
    var fetchButton: UIButton!
    var managedContext: NSManagedObjectContext!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置UI元素
        setupUI()

        // 设置CoreData上下文
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
            return
        }
        managedContext = appDelegate.persistentContainer.viewContext
    }

    func setupUI() {
        // 创建UILabel以显示存储数据
        dataLabel = UILabel()
        dataLabel.frame = CGRect(x: 20, y: 100, width: 300, height: 100)
        dataLabel.text = "Data will be shown here."
        dataLabel.numberOfLines = 0
        dataLabel.textAlignment = .center
        view.addSubview(dataLabel)

        // 创建UIButton以触发网络请求
        fetchButton = UIButton(type: .system)
        fetchButton.frame = CGRect(x: 20, y: 250, width: 300, height: 40)
        fetchButton.setTitle("Fetch Data", for: .normal)
        fetchButton.addTarget(self, action: #selector(fetchData), for: .touchUpInside)
        view.addSubview(fetchButton)
    }

    @objc func fetchData() {
        let urlString = "https://jsonplaceholder.typicode.com/posts/1"
        guard let url = URL(string: urlString) else {
            print("Invalid URL")
            return
        }
        // 发起请求
        sendRequest(with: url)
    }

    func sendRequest(with url: URL) {
        let session = URLSession.shared
        let task = session.dataTask(with: url) { data, response, error in
            if let error = error {
                print("Network error: \(error.localizedDescription)")
                return
            }

            // 确保响应成功
            guard let httpResponse = response as? HTTPURLResponse,
                  httpResponse.statusCode == 200 else {
                print("Failed to receive valid response")
                return
            }

            // 解析JSON数据
            if let data = data {
                do {
                    let post = try JSONDecoder().decode(Post.self, from: data)
                    self.savePostToCoreData(post: post)
                    DispatchQueue.main.async {
                        self.fetchDataFromCoreData()
                    }
                } catch {
                    print("Failed to decode JSON: \(error)")
                }
            }
        }
        task.resume()  // 执行请求
    }

    // 将API返回的数据保存到CoreData
    func savePostToCoreData(post: Post) {
        let entity = NSEntityDescription.entity(forEntityName: "PostEntity", in: managedContext)!
        let postObject = NSManagedObject(entity: entity, insertInto: managedContext)

        postObject.setValue(post.userId, forKey: "userId")
        postObject.setValue(post.id, forKey: "id")
        postObject.setValue(post.title, forKey: "title")
        postObject.setValue(post.body, forKey: "body")

        do {
            try managedContext.save()
            print("Data saved successfully.")
        } catch let error as NSError {
            print("Could not save. \(error), \(error.userInfo)")
        }
    }

    // 从CoreData读取数据并更新UI
    func fetchDataFromCoreData() {
        let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "PostEntity")

        do {
            let posts = try managedContext.fetch(fetchRequest)
            if let post = posts.first {
                let title = post.value(forKey: "title") as? String ?? "No title"
                let body = post.value(forKey: "body") as? String ?? "No body"
                dataLabel.text = "Title: \(title) \nBody: \(body)"
            }
        } catch let error as NSError {
            print("Could not fetch data. \(error), \(error.userInfo)")
        }
    }
}

// AppDelegate配置CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "PostModel")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        window = UIWindow(frame: UIScreen.main.bounds)
        let viewController = ViewController()
        window?.rootViewController = viewController
        window?.makeKeyAndVisible()
        return true
    }
}

代码说明如下:

  1. CoreData模型 :在 AppDelegate 中,我们配置了 NSPersistentContainer 来管理CoreData。persistentContainer 负责加载持久化存储并管理上下文(NSManagedObjectContext),该上下文用于处理数据操作。
  2. 数据模型PostPost 模型遵循 Codable 协议,用于解析API返回的JSON数据。每个 Post 对象包含 userIdidtitlebody 字段。
  3. CoreData操作savePostToCoreData(post:) 方法用于将API返回的数据保存到CoreData。首先,我们定义了一个 PostEntity 实体,该实体的属性与 Post 模型匹配。然后,将从API返回的数据保存到 PostEntity 的属性中,并通过 managedContext.save() 保存到数据库。fetchDataFromCoreData() 方法用于从CoreData中读取数据并更新UI。我们通过 NSFetchRequest 获取所有 PostEntity 对象,并显示第一个对象的标题和内容。
  4. 网络请求sendRequest(with:) 方法使用 URLSession 发起网络请求。当请求成功返回数据时,使用 JSONDecoder 将JSON数据解析为 Post 对象,并将该对象保存到CoreData中。保存数据后,应用会从CoreData中读取并更新UI。

在用户单击 Fetch Data 按钮后,应用将向 jsonplaceholder.typicode.com 发送请求并获取数据。假设请求成功并返回有效数据,控制台输出以下信息:

复制代码
Data saved successfully.

当数据成功保存到CoreData中,UI中的 UILabel 将显示从API获取的标题和内容,例如:

复制代码
Title: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
Body: quia et suscipit\nsuscipit...et id est laborum

本节演示了如何结合CoreData和SQLite进行数据存储,在iOS中实现持久化存储。通过将从DeepSeek API获取的数据保存到CoreData,并通过 NSFetchRequest 读取数据,我们可以在应用中实现高效的数据管理。使用CoreData不仅能简化数据库操作,还能提高数据持久化的效率,是实现本地存储和缓存的理想选择。

🔎6.4.2 文件管理与 UserDefaults

在移动应用中,文件管理与用户偏好设置的保存是两个常见的需求。iOS提供了多种方式来存储数据,其中 UserDefaults 和文件管理是最常见的两种选择。UserDefaults 用于存储小量的用户偏好数据,而文件管理则适用于存储更大或者复杂的结构化数据。通过合理使用这两者,可以有效地提高应用的数据存储能力。

UserDefaults 是iOS中用于存储小型、简单数据(如字符串、数字、布尔值等)的容器。通常用于保存应用的设置、用户偏好和轻量级的会话信息等。UserDefaults 的优点在于操作简单,可以直接存取数据,而无须像数据库那样进行复杂的管理。使用 UserDefaults 时,数据将持久化存储在设备上,并且在应用重新启动时可以获取。它并不适用于存储大量数据或复杂的对象(如大型图片、视频文件等)。

当应用需要存储较大数据时,例如图片、文档或音频文件,可以使用文件管理来实现。iOS提供了丰富的API用于管理文件,如通过 FileManager 来创建、读取、写入和删除文件。文件管理提供了灵活的存储方案,可以用于存储应用的配置文件、缓存数据等。

下面结合DeepSeek API的应用,展示如何使用 UserDefaults 和文件管理来处理和存储从DeepSeek API获取的数据。

【例6-9】 展示如何通过 UserDefaults 存储用户的偏好设置,并通过文件管理存储从DeepSeek API获取的数据。我们将实现以下功能:

  1. 将用户的配置信息存储到 UserDefaults
  2. 将API返回的JSON数据保存到应用的沙盒目录中。
  3. 从沙盒目录读取并展示存储的数据。
swift 复制代码
import UIKit

// 定义数据模型Post
struct Post: Codable {
    let userId: Int
    let id: Int
    let title: String
    let body: String
}

class ViewController: UIViewController {
    var dataLabel: UILabel!
    var fetchButton: UIButton!

    // 用户设置的键
    let userDefaultsKey = "UserSettings"
    let fileManager = FileManager.default

    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置UI元素
        setupUI()

        // 从UserDefaults读取用户设置
        readUserDefaults()
    }

    func setupUI() {
        // 创建UILabel以显示存储数据
        dataLabel = UILabel()
        dataLabel.frame = CGRect(x: 20, y: 100, width: 300, height: 100)
        dataLabel.text = "Data will be shown here."
        dataLabel.numberOfLines = 0
        dataLabel.textAlignment = .center
        view.addSubview(dataLabel)

        // 创建UIButton以触发网络请求
        fetchButton = UIButton(type: .system)
        fetchButton.frame = CGRect(x: 20, y: 250, width: 300, height: 40)
        fetchButton.setTitle("Fetch Data", for: .normal)
        fetchButton.addTarget(self, action: #selector(fetchData), for: .touchUpInside)
        view.addSubview(fetchButton)
    }

    @objc func fetchData() {
        let urlString = "https://jsonplaceholder.typicode.com/posts/1"
        guard let url = URL(string: urlString) else {
            print("Invalid URL")
            return
        }
        // 发起请求
        sendRequest(with: url)
    }

    func sendRequest(with url: URL) {
        let session = URLSession.shared
        let task = session.dataTask(with: url) { data, response, error in
            if let error = error {
                print("Network error: \(error.localizedDescription)")
                return
            }

            // 确保响应成功
            guard let httpResponse = response as? HTTPURLResponse,
                  httpResponse.statusCode == 200 else {
                print("Failed to receive valid response")
                return
            }

            // 解析JSON数据
            if let data = data {
                do {
                    let post = try JSONDecoder().decode(Post.self, from: data)
                    self.saveDataToFile(post: post)
                    DispatchQueue.main.async {
                        self.fetchDataFromFile()
                    }
                } catch {
                    print("Failed to decode JSON: \(error)")
                }
            }
        }
        task.resume()  // 执行请求
    }

    // 将数据保存到文件(沙盒)
    func saveDataToFile(post: Post) {
        // 获取沙盒路径
        guard let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
            return
        }
        let fileURL = documentDirectory.appendingPathComponent("postData.json")

        // 将数据转换为JSON并保存到文件
        do {
            let encoder = JSONEncoder()
            let data = try encoder.encode(post)
            try data.write(to: fileURL)
            print("Data saved to file.")
        } catch {
            print("Failed to save data to file: \(error)")
        }
    }

    // 从文件中读取数据
    func fetchDataFromFile() {
        // 获取沙盒路径
        guard let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
            return
        }
        let fileURL = documentDirectory.appendingPathComponent("postData.json")

        // 从文件读取数据
        do {
            let data = try Data(contentsOf: fileURL)
            let decoder = JSONDecoder()
            let post = try decoder.decode(Post.self, from: data)
            dataLabel.text = "Title: \(post.title)\nBody: \(post.body)"
        } catch {
            print("Failed to read data from file: \(error)")
        }
    }

    // 读取UserDefaults中的设置
    func readUserDefaults() {
        let defaults = UserDefaults.standard
        if let settings = defaults.dictionary(forKey: userDefaultsKey) {
            print("User settings retrieved from UserDefaults: \(settings)")
        } else {
            print("No user settings found in UserDefaults.")
        }
    }

    // 保存用户设置到UserDefaults
    func saveUserDefaults() {
        let defaults = UserDefaults.standard
        let settings: [String: Any] = [
            "theme": "Dark",
            "notificationsEnabled": true,
            "lastLogin": Date()
        ]
        defaults.set(settings, forKey: userDefaultsKey)
        print("User settings saved to UserDefaults.")
    }
}

// AppDelegate和其他必要的配置
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        window = UIWindow(frame: UIScreen.main.bounds)
        let viewController = ViewController()
        window?.rootViewController = viewController
        window?.makeKeyAndVisible()

        // 保存用户设置(只需执行一次)
        viewController.saveUserDefaults()

        return true
    }
}

代码说明如下:

  1. UserDefaults存储用户设置saveUserDefaults() 方法将一些基本的用户设置(如主题、通知开启状态、上次登录时间)保存到 UserDefaults。这些设置通常用于保存应用的用户偏好配置。通过 UserDefaults.standard.set() 方法,我们可以将数据以键值对的形式存储。存储的数据可以是 StringIntBool 等类型。
  2. 保存和读取文件数据saveDataToFile(post:) 方法将 Post 数据模型编码为JSON格式,并将其保存到应用的沙盒目录中的 postData.json 文件。这里使用了 JSONEncoder 来编码数据,Data.write(to:) 方法用于将数据写入文件。fetchDataFromFile() 方法读取存储在文件中的数据。通过 Data(contentsOf:) 方法读取文件内容,然后使用 JSONDecoder 将数据解码为 Post 对象。
  3. 网络请求与数据保存sendRequest(with:) 方法发起GET请求从API获取数据。当数据成功返回后,Post 对象被保存到文件中,并通过 fetchDataFromFile() 从文件中读取数据并更新UI。JSONDecoder 用于解码API返回的JSON数据,并通过 saveDataToFile(post:) 保存到文件中。
  4. UI更新与错误处理:所有的数据读取、保存和UI更新操作都在主线程中进行,确保UI能正确更新。对于任何可能出现的错误,代码中都进行了适当的错误捕获并打印错误信息。

在模拟器或真实设备上运行时,单击 Fetch Data 按钮后,应用将发送请求并把从API返回的数据保存到文件中。假设请求成功并返回有效数据,控制台输出以下信息:

复制代码
User settings saved to UserDefaults.
Data saved to file.

UI中的 UILabel 将显示以下内容:

复制代码
Title: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
Body: quia et suscipit\nsuscipit...et id est laborum

本节展示了如何在iOS中结合使用 UserDefaults 和文件管理来存储应用数据。通过 UserDefaults 存储简单的用户设置,并通过文件管理存储更复杂的数据(如API返回的JSON),我们可以高效地处理不同类型的数据存储需求。在开发中,根据数据的复杂性和大小选择合适的存储方案,可以显著提高应用的性能和可维护性。

🔎6.4.3 内存缓存与NSCache

在移动应用开发中,性能优化是一个重要的考量因素。对于频繁使用的数据,可以通过内存缓存来提高数据的访问速度。内存缓存能够有效地减少对磁盘的访问,从而优化数据加载的效率。iOS提供了多种缓存机制,其中 NSCache 是一个高效的内存缓存解决方案。

NSCache 是苹果提供的一种缓存类,它能够自动管理内存缓存。与 NSDictionary 等字典类不同,NSCache 会根据设备的内存压力自动清理不再使用的缓存对象。因此,它特别适合存储频繁读取但不需要持久化的数据(如API请求返回的数据)。使用 NSCache 时,我们可以将API返回的数据、图片等资源缓存到内存中,避免每次请求都进行网络访问,从而提高应用的响应速度和用户体验。

以下示例展示了如何使用 NSCache 缓存从DeepSeek API获取的数据。通过实现缓存策略,我们避免每次请求都访问网络,从而提高了数据加载的效率。

【例6-10】 结合DeepSeek API开发的实际场景,展示如何使用 NSCache 来缓存从API获取的数据。

swift 复制代码
import UIKit

// 定义数据模型Post
struct Post: Codable {
    let userId: Int
    let id: Int
    let title: String
    let body: String
}

class ViewController: UIViewController {
    var dataLabel: UILabel!
    var fetchButton: UIButton!

    // 创建一个NSCache对象来缓存数据
    var dataCache = NSCache<NSString, Post>()
    // 缓存键
    let cacheKey = "postDataCacheKey"

    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置UI元素
        setupUI()

        // 检查缓存中是否存在数据
        if let cachedPost = dataCache.object(forKey: cacheKey as NSString) {
            // 如果缓存中有数据,则直接显示
            displayData(post: cachedPost)
        } else {
            print("No cached data found. Fetching data from API...")
        }
    }

    func setupUI() {
        // 创建UILabel以显示存储数据
        dataLabel = UILabel()
        dataLabel.frame = CGRect(x: 20, y: 100, width: 300, height: 100)
        dataLabel.text = "Data will be shown here."
        dataLabel.numberOfLines = 0
        dataLabel.textAlignment = .center
        view.addSubview(dataLabel)

        // 创建UIButton以触发网络请求
        fetchButton = UIButton(type: .system)
        fetchButton.frame = CGRect(x: 20, y: 250, width: 300, height: 40)
        fetchButton.setTitle("Fetch Data", for: .normal)
        fetchButton.addTarget(self, action: #selector(fetchData), for: .touchUpInside)
        view.addSubview(fetchButton)
    }

    @objc func fetchData() {
        let urlString = "https://jsonplaceholder.typicode.com/posts/1"
        guard let url = URL(string: urlString) else {
            print("Invalid URL")
            return
        }
        // 发起请求
        sendRequest(with: url)
    }

    func sendRequest(with url: URL) {
        let session = URLSession.shared
        let task = session.dataTask(with: url) { data, response, error in
            if let error = error {
                print("Network error: \(error.localizedDescription)")
                return
            }

            // 确保响应成功
            guard let httpResponse = response as? HTTPURLResponse,
                  httpResponse.statusCode == 200 else {
                print("Failed to receive valid response")
                return
            }

            // 解析JSON数据
            if let data = data {
                do {
                    let post = try JSONDecoder().decode(Post.self, from: data)
                    // 将数据缓存到NSCache中
                    self.cacheData(post: post)
                    DispatchQueue.main.async {
                        self.displayData(post: post)
                    }
                } catch {
                    print("Failed to decode JSON: \(error)")
                }
            }
        }
        task.resume()  // 执行请求
    }

    // 缓存数据到NSCache
    func cacheData(post: Post) {
        dataCache.setObject(post, forKey: cacheKey as NSString)
        print("Data cached successfully.")
    }

    // 从缓存或网络加载数据并显示
    func displayData(post: Post) {
        dataLabel.text = "Title: \(post.title)\nBody: \(post.body)"
    }
}

// AppDelegate和其他必要的配置
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        window = UIWindow(frame: UIScreen.main.bounds)
        let viewController = ViewController()
        window?.rootViewController = viewController
        window?.makeKeyAndVisible()
        return true
    }
}

代码说明如下:

  1. 内存缓存NSCacheNSCache 是一个内存缓存容器,用于存储对象数据。在此示例中,dataCache 是一个 NSCache 对象,用于缓存从DeepSeek API获取的数据。NSCache 通过 setObject(_:forKey:) 方法将数据存入缓存,并通过 object(forKey:) 方法读取缓存的数据。NSCache 会根据内存压力自动清理不常使用的缓存对象,这对于避免内存占用过高非常有效。
  2. 缓存检查 :在视图加载时,应用会检查 NSCache 中是否存在缓存的 Post 对象。如果缓存中存在数据,则直接显示缓存的数据。否则,应用将发起网络请求来获取数据。
  3. 网络请求与数据存储sendRequest(with:) 方法使用 URLSession 发起GET请求从API获取数据。当请求成功并返回数据后,应用会解析返回的JSON并将其存储到 NSCache 中。之后,更新UI以显示数据。
  4. UI更新:当缓存中有数据时,UI直接显示缓存的数据;如果没有缓存数据,则从网络获取数据并缓存,然后更新UI。
  5. 缓存命中:如果数据已缓存,每次重新打开应用时,UI将直接显示缓存的数据,避免了重复的网络请求。这样可以显著提高应用的响应速度,特别是在网络状况不佳时。

在模拟器或真实设备上运行时,单击 Fetch Data 按钮后,应用将向 jsonplaceholder.typicode.com 发送请求并缓存从API返回的数据。假设请求成功并返回有效数据,控制台输出以下信息:

复制代码
Data cached successfully.

UILabel 会显示以下内容:

复制代码
Title: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
Body: quia et suscipit\nsuscipit...et id est laborum

如果用户重新打开应用,且数据已缓存,控制台将显示:

复制代码
Data cached successfully.

且UI中的 UILabel 依旧显示缓存的内容:

复制代码
Title: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
Body: quia et suscipit\nsuscipit...et id est laborum

本小节展示了如何使用 NSCache 进行内存缓存,以优化从DeepSeek API获取的数据的性能。通过 NSCache,应用可以将数据缓存在内存中,避免重复的网络请求,从而提高响应速度。该方法特别适用于需要频繁访问的数据,如API请求返回的数据、图片等。此外,使用 NSCache 可以避免不必要的内存占用,它会根据内存压力自动清理缓存内容。