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

SwiftUI注册功能Preview崩溃求助:数据处理代码引发异常

SwiftUI注册功能Preview崩溃问题解决

崩溃根源分析

  1. JSON解码类型不匹配:你的AccessibleData.json中,sex字段是字符串格式(如"true"),age字段是字符串格式(如"20"),但Student结构体中对应的sex是Bool类型、age是Int类型。JSONDecoder无法自动将字符串转换为Bool/Int,导致load函数触发fatalError,直接崩溃。
  2. 全局变量初始化触发崩溃:AccessibleGroup是全局变量,Preview启动时会立即执行load("AccessibleData.json"),解码失败直接终止进程,所以即使没点击注册按钮,Preview也会崩溃。
  3. 逻辑错误(非崩溃但影响功能):authenticateUser函数中,Vertify = true被写在判断分支外,会强制将验证状态设为true,导致后续逻辑失效。

修复步骤

1. 修正JSON数据类型

修改AccessibleData.json,将sex改为布尔值(移除引号),age改为数字(移除引号):

{
    "22371187":{
        "name":     "周舟舟",
        "id":       "22371187",
        "sex":      true,
        "birthday": "2003-09-29",
        "age":      20,
        "major":    "计算机"
    },
    "1":{
        "name":     "zzh",
        "id":       "1",
        "sex":      true,
        "birthday": "2003-09-29",
        "age":      20,
        "major":    "宇航学"
    },
    "22371188":{
        "name":     "黄小姐",
        "id":       "22371188",
        "sex":      false,
        "birthday": "2004-09-24",
        "age":      19,
        "major":    "经济学"
    },
    "22371189":{
        "name":     "张三",
        "id":       "22371189",
        "sex":      true,
        "birthday": "2003-07-19",
        "age":      20,
        "major":    "软件工程"
    },
    "22371190":{
        "name":     "李四",
        "id":       "22371190",
        "sex":      false,
        "birthday": "2003-08-23",
        "age":      20,
        "major":    "数学"
    },
    "22371191":{
        "name":     "王五",
        "id":       "22371191",
        "sex":      true,
        "birthday": "2004-09-29",
        "age":      19,
        "major":    "物理"
    }
}

2. 修复验证逻辑错误

修改authenticateUser函数,将Vertify = true移到匹配成功的分支内,移除强制赋值:

func authenticateUser(stuname: String, stuid: String) {
    // 重置状态
    Vertify = false
    HadRegi = false

    if stuid == "" || stuname == "" {
        alertType = .fail_nil
    } else if password == "" {
        alertType = .fail_codenil
    } else {
        // 验证学号姓名是否匹配
        if let stu = AccessibleGroup[stuid], stu.name == stuname {
            Vertify = true
        }
        
        // 检查是否已注册
        if let stu = UserInfo[stuid], stu.name == stuname {
            HadRegi = true
        }

        if Vertify {
            if password.count < 8 {
                alertType = .fail_codeless
            } else if HadRegi {
                alertType = .fail_hadregi
            } else {
                alertType = .success
                // 这里可以安全初始化User,因为已经验证过stuid存在于AccessibleGroup
                let newUser = User(
                    stuName: stuname, 
                    stuId: stuid, 
                    UserName: "", 
                    sex: AccessibleGroup[stuid]!.sex, 
                    birthday: AccessibleGroup[stuid]!.birthday, 
                    sign_major: AccessibleGroup[stuid]!.major, 
                    sign_hobbies: [], 
                    sign_mbti: "", 
                    sign_major_pre: [], 
                    sign_others: [], 
                    code: password, 
                    new: true, 
                    single: nil, 
                    inPushToOthers: false, 
                    inOthersPushMe: false, 
                    age: AccessibleGroup[stuid]!.age
                )
                Regisuccess = true
            }
        } else {
            // 添加验证失败的提示
            alertType = .fail_nil
        }
    }
}

3. 优化load函数避免崩溃(可选)

将load函数的fatalError改为返回可选值,避免解码失败直接崩溃:

func load<T: Decodable>(_ filename: String) -> T? {
    let data: Data
    
    guard let file = Bundle.main.url(forResource: filename, withExtension: nil) else {
        print("Couldn't find \(filename) in main bundle")
        return nil
    }
    
    do {
        data = try Data(contentsOf: file)
    } catch {
        print("Couldn't load \(filename) from main bundle:\n\(error)")
        return nil
    }
    
    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        print("Couldn't parse \(filename) as \(T.self):\n\(error)")
        return nil
    }
}

// 初始化时处理可选值
var AccessibleGroup: [String: Student] = load("AccessibleData.json") ?? [:]

验证修复

完成上述修改后,Preview应该可以正常启动,点击注册按钮时,学号姓名匹配逻辑会正常工作,不会再崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:45:55