Support Topics Documentation Slack YouTube Blog

iOS sdk save: does't call callback

I found this code in sdk file PersistenceServiceUtils

func update(entity: [String : Any], responseHandler: (([String : Any]) -> Void)!, errorHandler: ((Fault) -> Void)!) {
        let headers = ["Content-Type": "application/json"]
        let parameters = PersistenceHelper.shared.convertDictionaryValuesFromGeometryType(entity)
        if let objectId = entity["objectId"] as? String {
            BackendlessRequestManager(restMethod: "data/\(tableName)/\(objectId)", httpMethod: .put, headers: headers, parameters: parameters).makeRequest(getResponse: { response in
                if let result = ProcessResponse.shared.adapt(response: response, to: JSON.self) {
                    if result is Fault {
                        errorHandler(result as! Fault)
                    }
                    else {
                        if let updatedUser = ProcessResponse.shared.adapt(response: response, to: BackendlessUser.self) as? BackendlessUser,
                            Backendless.shared.userService.stayLoggedIn,
                            let current = Backendless.shared.userService.getCurrentUser(),
                            updatedUser.objectId == current.objectId,
                            let currentToken = current.userToken {
                            updatedUser.setUserToken(value: currentToken)
                            Backendless.shared.userService.setPersistentUser(currentUser: updatedUser)
                        }
                        else if let resultDictionary = (result as! JSON).dictionaryObject,
                            let responseDictionary = PersistenceHelper.shared.convertToBLType(resultDictionary) as? [String : Any] {
                            responseHandler(responseDictionary)
                        }
                    }
                }
            })
        }
    }

It leads to situation when the success callback of this method is never called

1st Problem is in Line 103:
let responseDictionary = PersistenceHelper.shared.convertToBLType(resultDictionary) as? [String : Any]

It never passes check in if which call it

2nd Problem is in line 94 a later
if let updatedUser = ProcessResponse.shared.adapt(response: response, to: Backendle...

When the condition is true (which is easy to reach) callback (neither success or fail) will never be called

Hi @Nikolai_Suvorov

Do you mean Swift SDK or iOS SDK? I cant find the PersistenceServiceUtils class in our iOS SDK.

Yes, sorry - Swift SDK

Hello, @Nikolai_Suvorov,

For the update method server can return error or dictionary with updated object.
If we receive error - the error handler is called.
If we receive dictionary - we just check its fields and values for necessary transformations (the convertToBLType method) - nothing should fail here.

Could you please provide an example when callback should be called but it doesn’t?

Regards,
Olha

Yes. Sure
I’m trying to update standard table Users with info like

▿ 4 elements
▿ 0 : 2 elements
- key : “email”
- value : shartax@gmail.com
▿ 1 : 2 elements
- key : “phone”
- value : +380 73 102 4122
▿ 2 : 2 elements
- key : “name”
- value : Artem
▿ 3 : 2 elements
- key : “objectId”
- value : 0EF04990-32AE-E393-FF17-821CF824B800

Please check the line 103
let responseDictionary = PersistenceHelper.shared.convertToBLType(resultDictionary) as ? [String : Any ]
convertToBLType retunes BackendlessUser object and when trying to cast it to [String : Any ] it fails and never calls callback

And according to line 94 - thank you for noticing, we’ll fix it so the BackendlessUser object will return in response. As a workaround for this table I can advise to use the update method of the UserService class instead.
The internal ticket BKNDLSS-20796 is created.

Regards,
Olha

if you plan to pass BackendlessUser object as a return value you’ll modify function signature, right?
I mean from
func update(entity: [String : Any ], responseHandler: (([String : Any ]) -> Void)!, errorHandler: ((Fault) -> Void)!) {
to
func update(entity: BackendlessUser, responseHandler: (([String : Any ]) -> Void)!, errorHandler: ((Fault) -> Void)!) {

I think it should be something like

    func update(entity: [String : Any], responseHandler: (([String : Any]) -> Void)!, errorHandler: ((Fault) -> Void)!) {
    let headers = ["Content-Type": "application/json"]
    let parameters = PersistenceHelper.shared.convertDictionaryValuesFromGeometryType(entity)
    if let objectId = entity["objectId"] as? String {
        BackendlessRequestManager(restMethod: "data/\(tableName)/\(objectId)", httpMethod: .put, headers: headers, parameters: parameters).makeRequest(getResponse: { response in
            if let result = ProcessResponse.shared.adapt(response: response, to: JSON.self) {
                if result is Fault {
                    errorHandler(result as! Fault)
                }
                else {
                    if let updatedUser = ProcessResponse.shared.adapt(response: response, to: BackendlessUser.self) as? BackendlessUser,
                        Backendless.shared.userService.stayLoggedIn,
                        let current = Backendless.shared.userService.getCurrentUser(),
                        updatedUser.objectId == current.objectId,
                        let currentToken = current.userToken {
                        updatedUser.setUserToken(value: currentToken)
                        Backendless.shared.userService.setPersistentUser(currentUser: updatedUser)
                    }
                    
                    if let resultDictionary = (result as! JSON).dictionaryObject {
                        responseHandler(resultDictionary)
                    }
                }
            }
        })
    }
}

The BKNDLSS-20796 ticket is created. We’ll investigate this issue and fix it as soon as possible.
As a workaround you can update user object using the update method form UserService.

Regards,
Olha

Thanks

Issue has been fixed.
Could you please update to v5.7.7 and verify whether it works now?

Regards,
Olha