David Buik
David Buik

Reputation: 572

Could not cast value of type '__NSSingleObjectArrayI' to 'NSString'

When the iOS app trigger an API event named "addtocart" the app crashes returning below error.

url https://example.com/index.php/?route=api/cart/addToCart params
["product_id": "12098", "option": "{\n\n}", "quantity": "0", "token":
"2f42lqjie21cbzr1r0gsgphqtl", "width": "750.000000"] {
    error = 1;
    message =     (
        "Color required!"
    ); } Could not cast value of type '__NSSingleObjectArrayI' (0x1b5bee3b0) to 'NSString' (0x1b5bfaad8). 2018-08-02
19:50:28.493678+0300 Ishtari[35479:3846514] Could not cast value of
type '__NSSingleObjectArrayI' (0x1b5bee3b0) to 'NSString'
(0x1b5bfaad8). warning: could not execute support code to read
Objective-C class data in the process. This may reduce the quality of
type information available. (lldb)

The product has option called color so before adding to cart the user should choose the color of the item to checkout. The app is return the option name "Color" but not giving me the values to pick from ("option": "{\n\n}") which causing the app to crash giving above error when callingHTTPApi.

   func callingHttppApi(){
        DispatchQueue.main.async{
            NetworkManager.sharedInstance.showLoader()
            let sessionId = self.defaults.object(forKey:"ic_token");
            let width = String(format:"%f", SCREEN_WIDTH * UIScreen.main.scale)
            self.view.isUserInteractionEnabled = false
            
            if self.whichApiToProcess == "addtocart"{
                var requstParams = [String:String]();
                requstParams["width"] = width
                requstParams["product_id"] = self.productId
                requstParams["ic_token"] = sessionId as? String
                requstParams["quantity"] = self.quantityValue.text
                do {
                    let jsonSortData =  try JSONSerialization.data(withJSONObject: self.optionDictionary, options: .prettyPrinted)
                    let jsonSortString:String = NSString(data: jsonSortData, encoding: String.Encoding.utf8.rawValue)! as String
                    requstParams["option"] = jsonSortString
                }
                catch {
                    print(error.localizedDescription)
                }
                
                
                NetworkManager.sharedInstance.callingHttpRequest(params:requstParams, apiname:"cart/addToCart", cuurentView: self){success,responseObject in
                    if success == 1{
                        let dict = responseObject as! NSDictionary;
                        NetworkManager.sharedInstance.dismissLoader()
                        if dict.object(forKey: "fault") != nil{
                            let fault = dict.object(forKey: "fault") as! Bool;
                            if fault == true{
                                self.loginRequest()
                            }
                        }else{
                            print(dict)
                            self.view.isUserInteractionEnabled = true
                            let dict = responseObject as! NSDictionary
                            if dict.object(forKey: "error") as! Int == 0{
                                NetworkManager.sharedInstance.showSuccessSnackBar(msg: dict.object(forKey: "message") as! String)
                                let data = dict.object(forKey: "total") as! String
                                self.tabBarController!.tabBar.items?[3].badgeValue = data.components(separatedBy: " ")[0]
                                self.navigationCart(cartCount:data.components(separatedBy: " ")[0])
                                if self.goToBagFlag == true{
                                    self.tabBarController!.selectedIndex = 3
                                }
                                
                            }else{
                                NetworkManager.sharedInstance.showWarningSnackBar(msg: dict.object(forKey: "message") as! String)
                            }
                        }
                    }else if success == 2{
                        NetworkManager.sharedInstance.dismissLoader()
                        self.callingHttppApi()
                    }
                }
            }

When it crashes the console directs me to this line

                        }else{
                            NetworkManager.sharedInstance.showWarningSnackBar(msg: dict.object(forKey: "message") as! String)
                        }

Any help please!

Upvotes: 0

Views: 2591

Answers (1)

vadian
vadian

Reputation: 285220

The error is clear:

Could not cast value of type '__NSSingleObjectArrayI' (0x1b5bee3b0) to 'NSString' (0x1b5bfaad8)

The left side shows the actual type (Array), the right side is what you are doing wrong (String)

NetworkManager.sharedInstance.showWarningSnackBar(msg: dict.object(forKey: "message") as! [String])

If msg is supposed to be String join the strings

let messageArray = dict.object(forKey: "message") as! [String] 
NetworkManager.sharedInstance.showWarningSnackBar(msg: messageArray.joined(separator: ", "))

By the way use Swift native types and key subscription

let dict = responseObject as! [String:Any]
...
NetworkManager.sharedInstance.showWarningSnackBar(msg: dict["message"] as! [String])

And – sorry – this syntax is horrible:

let jsonSortString:String = NSString(data: jsonSortData, encoding: String.Encoding.utf8.rawValue)! as String

Please replace it with

let jsonSortString = String(data: jsonSortData, encoding: .utf8)!

Upvotes: 0

Related Questions