Swift ui Escaping closure captures mutating 'self' parameter

Viewed 262

I am having the following problem when used in init(), can anyone help me out?

enter image description here

    @State private var activity: [ResponseActivity] = [ResponseActivity()]

    func getActivity(completion: @escaping ([ResponseActivity]?) -> ()){
        var userInfo: [ResponseActivity] = [ResponseActivity()]
        let url = URL(string: "https://api.github.com/users/\(self.userInfo.login)/received_events")!
        let urlRequest = URLRequest(url: url)
        
        print("self.userInfo.login", self.userInfo.login)
        
        let task = URLSession.shared.dataTask(with: urlRequest) { data, urlResponse, error in
            guard let content = data else {
                print("Error getting data from API.")
                return
            }
            
            do {
                userInfo = try JSONDecoder().decode([ResponseActivity].self, from: content)
            } catch {
                print("Error parsing URL from data Activity.")
                return
            }
            completion(userInfo)
        }
        task.resume()
    }
1 Answers

Properties in a struct like this (View) are immutable. You can set initial values inside init, but then they aren't mutable later. Special property wrappers like @State let you mutate values later on, but you're attempting to set the actual value on the struct by using _activity = State(...).

I'd suggest moving asynchronous code like this to an ObservableObject -- then, you'll have a class with mutable properties. This will mean that your userInfo, isLogin, etc will be @Published properties and will probably need to be optionals, since they won't have values until getActivity completes.

Related