You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SwiftUI中使用@AppStorage存储枚举类型?以MKMapType存储到UserDefaults为例

关于SwiftUI中@AppStorage存储枚举类型的问题解答

首先直接给你结论:你完全可以直接使用@AppStorage("myMapType") var mapType: MKMapType = .standard来存储地图类型,不需要手动去存取rawValue——下面我详细解释原因和通用方法:

为什么MKMapType可以直接用@AppStorage?

MKMapType本质是一个基于Int的枚举,它自动遵循了RawRepresentable协议(所有带rawValue的枚举默认都会遵循)。而@AppStorage原生支持存储遵循RawRepresentable且其RawValue属于Property List兼容类型(比如Int、String、Bool等)的类型。SwiftUI会自动帮你完成枚举和rawValue之间的序列化、反序列化工作,你完全不用手动处理。

举个实际使用的例子:

import SwiftUI
import MapKit

struct MapView: View {
    // 直接用@AppStorage存储MKMapType
    @AppStorage("myMapType") var mapType: MKMapType = .standard
    
    var body: some View {
        Map(mapType: $mapType)
        Button("切换到卫星视图") {
            mapType = .satellite
        }
    }
}

当你点击按钮切换地图类型时,@AppStorage会自动把新的MKMapType的rawValue写入UserDefaults,下次启动App时也会自动读取恢复状态。

SwiftUI中存储枚举类型的通用方法

根据枚举的类型不同,处理方式分为两种:

1. 带RawValue的枚举(最常见)

只要你的枚举是基于Int、String等@AppStorage支持的类型定义的,直接用@AppStorage即可,和上面的MKMapType用法完全一致。

比如自定义一个主题枚举:

enum AppTheme: String {
    case light, dark, auto
}

// 直接存储
@AppStorage("selectedTheme") var currentTheme: AppTheme = .auto

2. 带关联值的枚举(无默认RawValue)

如果你的枚举包含关联值(比如enum Preference { case volume(Double); case notifications(Bool) }),这类枚举默认没有rawValue,需要手动实现RawRepresentable协议,将其转换为Data类型(因为Data是@AppStorage支持的类型)来存储。

示例代码:

// 带关联值的枚举
enum UserPreference {
    case defaultVolume(Double)
    case notificationsEnabled(Bool)
}

// 实现RawRepresentable,用JSON序列化/反序列化
extension UserPreference: RawRepresentable, Codable {
    typealias RawValue = Data
    
    init?(rawValue: RawValue) {
        do {
            self = try JSONDecoder().decode(UserPreference.self, from: rawValue)
        } catch {
            print("反序列化失败:\(error)")
            return nil
        }
    }
    
    var rawValue: RawValue {
        do {
            return try JSONEncoder().encode(self)
        } catch {
            print("序列化失败:\(error)")
            return Data()
        }
    }
}

// 现在就可以用@AppStorage存储了
@AppStorage("userPreferences") var userPrefs: UserPreference = .defaultVolume(0.7)

总结

  • 对于像MKMapType这种自带兼容RawValue的枚举,直接用@AppStorage即可,无需手动处理rawValue;
  • 自定义带RawValue的枚举,只要RawValue是Property List兼容类型,直接用@AppStorage;
  • 带关联值的枚举,需要手动实现RawRepresentable(结合Codable来序列化/反序列化是最便捷的方式),转为Data后再用@AppStorage存储。

内容的提问来源于stack exchange,提问作者Peter Plass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 08:42:44