App全局配置表设计

简介: 运营过程中,我们会碰到需要以App版本为维度,去定制一些App配置变量

概述

运营过程中,我们会碰到需要以App版本为维度,去定制一些App配置变量。如版本更新描述,App最低可用版本等。有时也会需要有动态变更一些配置的能力,比如客诉反馈邮箱,促销活动入口开闭等。

为此,我们设计了App全局配置表模块,即可是满足集中管理App配置,也能满足App配置动态变更的需求。

配置的管理与下发

我们需要为客户端提供一个的服务端API,用于配置表的下发,多为JSON表的形式。

下面是一个简单的实现,客户端上报版本号和请求时间,服务端可以根据版本号来选择下发的配置表。

随着配置表的演进,服务端会把配置迁移到数据库存储,再衍生出后台进行可视化的配置管理。

type AppGlobalConfigRequest struct {
   
    BuildVersion string `json:"build_version"  binding:"required"`
    AppVersion   string `json:"app_version"  binding:"required"`
    Time         string `json:"time"  binding:"required"`
}

func AppGlobalConfig(w http.ResponseWriter, r *http.Request) {
   
  var reqBody map[string]interface{
   }
    if err := json.NewDecoder(r.Body).Decode(&reqBody); err != nil {
   
        log.Printf("AppGlobalConfig reqBody json.NewDecoder: %v", err)
        http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
        return
    }

    var reqParams AppGlobalConfigRequest
    data := reqBody["data"]
    dataJSONString, _ := json.Marshal(data)
    if err := json.Unmarshal([]byte(dataJSONString), &reqParams); err != nil {
   
        log.Printf("AppGlobalConfig reqParams json.Unmarshal: %v", err)
        http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
        return
    }

    config := map[string]interface{
   }{
   
        "version":                  2022091901,
        "user_initial_trial_count": 2,
        "create_date":              "2022-09-19T02:58:31Z",
    }
    response := map[string]interface{
   }{
   
        "data": config,
    }
    responseString, _ := json.Marshal(response)
    fmt.Fprintf(w, string(responseString))
}
AI 代码解读

配置的更新与持久化

配置的更新

为了保证配置的实效性,App初始化时,以及App从后台唤醒时,都需要检测配置的更新。

class AppConfigModule: SpaceportModuleProtocol {
   
    var loaded = false

    static func modulePriority() -> Int {
    return 2895 }

    func loadModule() {
   
        AppConfigManager.shared.fetchGlobalConfig()
    }

    func unloadModule() {
    }

    func applicationWillEnterForeground(notification: Notification) {
   
        AppConfigManager.shared.fetchGlobalConfig()
    }
}
AI 代码解读

配置表模型

配置表里包含了三个字段,其中userInitialTrialCount是配置信息,configVersioncreateDate均为配置表的描述信息。

本地的配置表需要有默认值。当出现API请求失败,或者API配置表解析错误时,可以用默认配置保证功能正常使用。

private let defaultUserInitialTrialCount = 2
public struct GlobalConfig: Codable {
   
    /// 配置版本号
    let configVersion: Int
    /// 用户初始试用次数
    let userInitialTrialCount: Int
    /// 生成时间 如:2022-09-19T02:58:31Z
    let createDate: String

    enum CodingKeys: String, CodingKey {
   
        case configVersion = "version"
        case userInitialTrialCount = "user_initial_trial_count"
        case createDate = "create_date"
    }

    init() {
   
        self.configVersion = 0
        self.userInitialTrialCount = defaultUserInitialTrialCount
        self.createDate = Date().axv.toISO8601String()
    }
}
AI 代码解读

配置表持久化

配置表的持久化和一般模型的持久化基本相同,可以选择Sqlite,JSON File,甚至内存缓存的形式,可根据配置表的数据规模和响应要求来选择。

目前我们选用UserDefault来管理配置表的持久化,即用Plist文件存储的配置表信息。

为了避免配置表频繁持久化,需要对配置的版本进行筛选,低于当前环境的版本可以被抛弃。

enum AppConfig: String {
   
    /// App全局配置 GlobalConfig
    case globalConfig
}

private let appConfigUserDefaults = UserDefaultsManager(suiteName: "com.pe.AppConfig").userDefaults

extension AppConfig: UserDefaultPreference {
   
    var userDefaults: UserDefaults {
    return appConfigUserDefaults }
}

class AppConfigManager {
   
    public static let shared = AppConfigManager()
    private init() {
   }

    lazy var globalConfig: GlobalConfig = {
   
        guard let config = AppConfig.globalConfig.codableObject(GlobalConfig.self) else {
   
            return GlobalConfig()
        }
        return config
    }() {
   
        didSet {
   
            AppConfig.globalConfig.save(codableObject: globalConfig)
        }
    }

    /// 获取配置
    func fetchGlobalConfig() {
   
        Task {
   
            do {
   
                if let config = try await GlobalConfigRequest().request() {
   
                    if config.configVersion > globalConfig.configVersion {
   
                        globalConfig = config
                        logDebug("GlobalConfig Updated: \(globalConfig)", tag: .kLogTag)
                    }
                }
            } catch {
   
                logWarn("got error: \(error)", tag: .kLogTag)
            }
        }
    }
}
AI 代码解读

总结

配置表下发是一种常用的App配置动态管理方案。

设计方案时需要满足快速的响应速度,便捷的存取API,方便维护的模型,以及对机能的低消耗。

根据业务场景的不同,还可以扩展出配置表版本管理,多级配置表的关联使用,配置信息变更通知等不同的不同的功能点。

gin桦
+关注
目录
打赏
0
0
0
0
1
分享
相关文章
【一步步开发AI运动APP】七、自定义姿态动作识别检测——之规则配置检测
本文介绍了如何通过【一步步开发AI运动APP】系列博文,利用自定义姿态识别检测技术开发高性能的AI运动应用。核心内容包括:1) 自定义姿态识别检测,满足人像入镜、动作开始/停止等需求;2) Pose-Calc引擎详解,支持角度匹配、逻辑运算等多种人体分析规则;3) 姿态检测规则编写与执行方法;4) 完整示例展示左右手平举姿态检测。通过这些技术,开发者可轻松实现定制化运动分析功能。
|
17天前
《仿盒马》app开发技术分享-- 首页活动配置(5)
上一篇文章中我们实现了项目端云一体化首页部分模块动态配置,实现了对模块模块的后端控制显示和隐藏,这能让我们的app更加的灵活,也能应对更多的情况。现在我们来对配置模块进行完善,除了已有的模块以外,我们还有一些banner ,活动入口等模块,这些模块的数据并不多,所以我们也归纳到配置中去实现。并且我们在配置表中添加了一些不同的id,我们只需要根据相对应的id 去查询对应的表就可以了
16 0
苹果app上架-ios上架苹果商店app store 之苹果支付In - App Purchase内购配置-优雅草卓伊凡
苹果app上架-ios上架苹果商店app store 之苹果支付In - App Purchase内购配置-优雅草卓伊凡
261 13
苹果app上架-ios上架苹果商店app store 之苹果支付In - App Purchase内购配置-优雅草卓伊凡
【Azure App Service】分享使用Python Code获取App Service的服务器日志记录管理配置信息
本文介绍了如何通过Python代码获取App Service中“Web服务器日志记录”的配置状态。借助`azure-mgmt-web` SDK,可通过初始化`WebSiteManagementClient`对象、调用`get_configuration`方法来查看`http_logging_enabled`的值,从而判断日志记录是否启用及存储方式(关闭、存储或文件系统)。示例代码详细展示了实现步骤,并附有执行结果与官方文档参考链接,帮助开发者快速定位和解决问题。
121 23
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
231 28
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
【Azure App Service】App Service 如何配置私网域名以及证书呢?
本文解答了关于 Azure App Service 如何配置私网域名及证书的问题。App Service 不支持私网域名,自定义域名需配置在公共 DNS 服务器上。文章引用官方文档详细说明了映射自定义 DNS 的步骤,并附带参考资料链接,帮助用户深入了解相关配置方法。
|
4月前
|
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
322 0
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
236 3
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
286 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问