简体   繁体   中英

@ObservedObject not updating after successful network call

I've hit a brick wall in my widget extension. I'm using AlamoFire and ObjectMapper to match the networking we have in the main app. I can tell that my AlamoFire network call is getting triggered and that I'm getting results back, and in the correct, expected format. However, saving the response of that network call to a @Published var doesn't seem to be working. My view and models/structs are below:

struct WidgetEntryView: View {
    var entry: ResourceCategoryEntry

    @ObservedObject var viewModel = WidgetResourcesView(widgetSize: .medium)

    var body: some View {
        if UserDefaults.forAppGroup.object(forKey: "sessionToken") as? String == nil {
            PleaseLogIn()
        } else if viewModel.mediumResources.count < 1 {
            ErrorScreen()
        } else {
            MediumResourcesView(resources: viewModel.mediumResources)
        }
    }
}
class WidgetResourcesView: ObservableObject {

    @Published var resourceGroups: [WidgetResouceGroup] = [WidgetResouceGroup]()

    var widgetSize: WidgetSize = .small
    var selectedCategory: String?

    init(widgetSize: WidgetSize) {
        self.widgetSize = widgetSize
        self.selectedCategory = UserDefaults.forAppGroup.string(forKey: ResourceCategoryEntry.userDefaultKey)
        getResources()
    }

    func getResources() {
        WidgetNetworkService.getResources(widgetSize: self.widgetSize.rawValue, selectedCategory: self.selectedCategory) { resourceGroups in
            DispatchQueue.main.async {
                self.resourceGroups = resourceGroups
            }
        } failure: { _ in
            print("Error Received")
        }
    }

    var mediumResources: [WidgetResource] {
        var resources = [WidgetResource]()

        if let featuredResourceGroup = resourceGroups.featuredResourceGroup {
            for resource in featuredResourceGroup.resources { resources.append(resource) }
        }

        if let nonFeaturedResourceGroup = resourceGroups.nonFeaturedResourceGroup {
            for resource in nonFeaturedResourceGroup.resources { resources.append(resource) }
        }

        return resources
    }

}

class WidgetResouceGroup: NSObject, Mappable, Identifiable {

    var id = UUID()
    var widgetCategory: WidgetCategory = .featured
    var resources = [WidgetResource]()

    required init?(map: Map) {}

    func mapping(map: Map) {
        id <- map["section"]
        widgetCategory <- map["section"]
        resources <- map["resources"]
    }

}

typealias WidgetResourceGroupCollection = [WidgetResouceGroup]

extension WidgetResourceGroupCollection {

    var featuredResourceGroup: WidgetResouceGroup? {
        return first(where: {$0.widgetCategory == .featured})
    }

    var nonFeaturedResourceGroup: WidgetResouceGroup? {
        return first(where: {$0.widgetCategory != .featured})
    }

}

class WidgetResource: NSObject, Mappable, Identifiable {
    enum ResourceType: String {
        case text = "text"
        case audio = "audio"
        case video = "video"
    }

    var id = 0
    var title = ""
    var imageInfo: WidgetImageInfo?
    var resourceType: ResourceType = .text

    required init?(map: Map) {}

    func mapping(map: Map) {
        id <- map["object_id"]
        title <- map["title"]
        imageInfo <- map["image_info"]
        resourceType <- map["content_type"]
    }
}

You can use the objectWillChange - Property in your observable object to specifiy when the observable object should be refreshed.

Apple Dev Doku Example by Paul Hudson

WidgetEntryView instantiates WidgetResourcesView using the ObservedObject wrapper. This causes a new instance of WidgetResourcesView to be instantiated again on every refresh. Try switching that to StateObject, and the original object will be kept in memory between view updates. I believe this is the only change needed, but I'm away so can't test it!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM