首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift领域:写入数据库的不正确对象

Swift领域:写入数据库的不正确对象
EN

Stack Overflow用户
提问于 2022-02-10 20:46:48
回答 2查看 37关注 0票数 1

下面是一个从领域添加/获取数据的类:

代码语言:javascript
复制
import Foundation
import RealmSwift

class WeatherDataOneDay {
    var temperature: Int = 0
    var temperatureDescription: String = ""
    var condition: Int = 0
    var city: String = ""
    var weatherIconName: String = ""
    var sunset: Double = 0
    var sunrise: Double = 0
    var humidity: Int = 0
    var windSpeed: Float = 0.0
    var date: Double = 0
    var feelsLike: Int = 0
    
    var clouds: Int = 0
    var lon: Float = 0.0
    var lat: Float = 0.0
    
    func printSelf()
    {
        print("temperature : \(temperature)")
        print("temperatureDescription : \(temperatureDescription)")
        print("condition : \(condition)")
        print("city : \(city)")
        print("weatherIconName : \(weatherIconName)")
        print("sunset : \(sunset)")
        print("sunrise : \(sunrise)")
        print("humidity : \(humidity)")
        print("windSpeed : \(windSpeed)")
        print("date : \(date)")
        print("feelsLike : \(feelsLike)")
        print("clouds : \(clouds)")
        print("lon : \(lon)")
        print("lat : \(lat)")
    }
}

@objcMembers class WeatherDataOneDayCached: Object {
    dynamic var poi: String?
    
    dynamic var temperature: Int?
    dynamic var temperatureDescription: String?
    dynamic var condition: Int?
    dynamic var city: String?
    dynamic var weatherIconName: String?
    dynamic var sunset: Double?
    dynamic var sunrise: Double?
    dynamic var humidity: Int?
    dynamic var windSpeed: Float?
    dynamic var date: Double?
    dynamic var feelsLike: Int?
    dynamic var clouds: Int?
    dynamic var lon: Float?
    dynamic var lat: Float?

    override static func primaryKey() -> String? {
        return "poi"
    }
    
    func printSelf()
    {
        print("temperature : \(temperature)")
        print("temperatureDescription : \(temperatureDescription)")
        print("condition : \(condition)")
        print("city : \(city)")
        print("weatherIconName : \(weatherIconName)")
        print("sunset : \(sunset)")
        print("sunrise : \(sunrise)")
        print("humidity : \(humidity)")
        print("windSpeed : \(windSpeed)")
        print("date : \(date)")
        print("feelsLike : \(feelsLike)")
        print("clouds : \(clouds)")
        print("lon : \(lon)")
        print("lat : \(lat)")
    }

}

class WeatherDataOneDayDbProvider {
    private var realm: Realm?
    
    init() {
        var config = Realm.Configuration()
        config.fileURL = config.fileURL!.deletingLastPathComponent().appendingPathComponent("weather_data_one_day.realm")
        realm = try? Realm(configuration: config)        
    }
            
    func getOneDayWeatherDataForPoi(poi : String) -> WeatherDataOneDay? {
        let weatherData = realm?.object(ofType: WeatherDataOneDayCached.self, forPrimaryKey: poi)
        if let weatherData = weatherData {
            let result = WeatherDataOneDay()
            result.temperature = weatherData.temperature ?? 0
            result.temperatureDescription = weatherData.temperatureDescription ?? ""
            result.condition = weatherData.condition ?? 0
            result.city = weatherData.city ?? ""
            result.weatherIconName = weatherData.weatherIconName ?? ""
            result.sunset = weatherData.sunset ?? 0.0
            result.sunrise = weatherData.sunrise ?? 0.0
            result.humidity = weatherData.humidity ?? 0
            result.windSpeed = weatherData.windSpeed ?? 0.0
            result.date = weatherData.date ?? 0.0
            result.feelsLike = weatherData.feelsLike ?? 0
            result.clouds = weatherData.clouds ?? 0
            result.lon = weatherData.lon ?? 0.0
            result.lat = weatherData.lat ?? 0.0
            
            return result
        } else {
            return nil
        }
    }
    
    func addOneDayWeatherDataForPoi(poi : String, weatherData: WeatherDataOneDay) {
        let cachedWeatherData = WeatherDataOneDayCached()
        cachedWeatherData.poi = poi
        
        cachedWeatherData.temperature = weatherData.temperature
        cachedWeatherData.temperatureDescription = weatherData.temperatureDescription
        cachedWeatherData.condition = weatherData.condition
        cachedWeatherData.city = weatherData.city
        cachedWeatherData.weatherIconName = weatherData.weatherIconName
        cachedWeatherData.sunset = weatherData.sunset
        cachedWeatherData.sunrise = weatherData.sunrise
        cachedWeatherData.humidity = weatherData.humidity
        cachedWeatherData.windSpeed = weatherData.windSpeed
        cachedWeatherData.date = weatherData.date
        cachedWeatherData.feelsLike = weatherData.feelsLike
        cachedWeatherData.clouds = weatherData.clouds
        cachedWeatherData.lon = weatherData.lon
        cachedWeatherData.lat = weatherData.lat
                
        if isWeatherDataExist(poi: poi) {
            try? realm?.write {
                realm?.add(cachedWeatherData, update: .all)
            }
        } else {
            try? realm?.write {
                realm?.add(cachedWeatherData)
            }
        }
    }
        
    func isWeatherDataExist(poi: String) -> Bool {
        return realm?.object(ofType: WeatherDataOneDayCached.self, forPrimaryKey: poi) != nil
    }
}

class WeatherDataOneDayDB {
    private let dbDataProvider : WeatherDataOneDayDbProvider = WeatherDataOneDayDbProvider()
    
    static var shared: WeatherDataOneDayDB = {
        let instance = WeatherDataOneDayDB()
        return instance
    }()

    private init() {}
    
    func getOneDayWeatherDataForPoi(poi : String) -> WeatherDataOneDay? {
        return dbDataProvider.getOneDayWeatherDataForPoi(poi: poi)
    }
    
    func addOneDayWeatherDataForPoi(poi : String, weatherData: WeatherDataOneDay) {
        return dbDataProvider.addOneDayWeatherDataForPoi(poi: poi, weatherData: weatherData)
    }
}

这是一个测试片段:

代码语言:javascript
复制
let test = WeatherDataOneDay()
test.temperature = 26
test.temperatureDescription = "clear sky"
test.condition = 800
test.city = "Globe"
test.weatherIconName = ""
test.sunset = 1644517064.0
test.sunrise = 1644473452.0
test.humidity = 80
test.windSpeed = 2.4
test.date = 1644521917.0
test.feelsLike = 29
test.clouds = 0
test.lon = 0.0
test.lat = 0.0
print("!!!!!!!DEBUUUUUUUUG!!!!!!!!!!!")
let db = WeatherDataOneDayDB.shared
db.addOneDayWeatherDataForPoi(poi: "Москва",
                              weatherData: test)

if let obj = db.getOneDayWeatherDataForPoi(poi: "Москва") {
    obj.printSelf()
}

我看到对象并不是完全写到DB中的--只有少数成员是可以的,其余的都是零。这就是我所收到的:

代码语言:javascript
复制
temperature : 0
temperatureDescription : clear sky
condition : 0
city : Globe
weatherIconName : 
sunset : 0.0
sunrise : 0.0 ....

我只从主线程访问DB。我遗漏了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-21 17:35:07

首先,避免可选的主键,这是没有意义的。我建议在对象定义中使用现代语法:

代码语言:javascript
复制
class WeatherDataOneDayCached: Object {
    @Persisted(primaryKey: true) var poi: String
    @Persisted var temperature: Int?
    ...
}

只有这样才能解决这个问题。此外,还可以为db提供程序提供更快速的代码:

代码语言:javascript
复制
class WeatherDataOneDayDbProvider {
private var realm: Realm // No need to have it optional if you can't continue without one

init() {
    var config = Realm.Configuration()
    ...
    realm = try! Realm(configuration: config) // Just add exceptions handling or ! for prototyping
}
        
func getOneDayWeatherDataForPoi(poi : String) -> WeatherDataOneDay? {
    // Save some lines here too
    guard let weatherData = realm.object(ofType: WeatherDataOneDayCached.self, forPrimaryKey: poi) else {
        return nil
    }
    let result = WeatherDataOneDay()
    result.temperature = weatherData.temperature ?? 0
    ...
    return result
}

func addOneDayWeatherDataForPoi(poi : String, weatherData: WeatherDataOneDay) {
    try? realm.write {
        // get available object or create new in a single line
        let cachedWeatherData = realm.object(ofType: WeatherDataOneDayCached.self, forPrimaryKey: poi) ??
        realm.create(WeatherDataOneDayCached.self, value: ["poi": poi])

        cachedWeatherData.temperature = weatherData.temperature
        ...
    }
}

}

printSelf()的长定义不同,您可以直接在代码中编写dump(object)

票数 1
EN

Stack Overflow用户

发布于 2022-02-11 00:04:39

下面是我的案例的解决方案(似乎在某种程度上是可选用法的问题):

代码语言:javascript
复制
class WeatherDataOneDayCached: Object {
    @objc dynamic var poi: String = ""
    
    @objc dynamic var temperature: Int = 0
    @objc dynamic var temperatureDescription: String = ""
    @objc dynamic var condition: Int = 0
    @objc dynamic var city: String = ""
    @objc dynamic var weatherIconName: String = ""
    @objc dynamic var sunset: Double = 0
    @objc dynamic var sunrise: Double = 0
    @objc dynamic var humidity: Int = 0
    @objc dynamic var windSpeed: Float = 0
    @objc dynamic var date: Double = 0
    @objc dynamic var feelsLike: Int = 0
    @objc dynamic var clouds: Int = 0
    @objc dynamic var lon: Float = 0
    @objc dynamic var lat: Float = 0

    override static func primaryKey() -> String? {
        return "poi"
    }
    
    func printSelf()
    {
        print("temperature : \(temperature)")
        print("temperatureDescription : \(temperatureDescription)")
        print("condition : \(condition)")
        print("city : \(city)")
        print("weatherIconName : \(weatherIconName)")
        print("sunset : \(sunset)")
        print("sunrise : \(sunrise)")
        print("humidity : \(humidity)")
        print("windSpeed : \(windSpeed)")
        print("date : \(date)")
        print("feelsLike : \(feelsLike)")
        print("clouds : \(clouds)")
        print("lon : \(lon)")
        print("lat : \(lat)")
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71072058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档