0

I have a class in swift which makes the dictionary using strings in keys and objects in values. eg let dict = ["key":value.key]. the value is always a string.

When i get the data in my objective c class, for one the object type is

_TtGCs26_SwiftDeferredNSDictionaryVs11AnyHashableP__$

and the code is expecting nsdictionary.

Now when the code -

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dictionaryFromSwiftClass];

is executed, the program throws the error

********[1235:641121] -[__SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x280571380
//making dict in swift class

let dictForAddToCart:NSDictionary = 
[
    "assoc_prod":[

        ["assoc_prodID":"92",
         "assoc_prodValue":currentSelectedColor,
         "productInfo":[
             "code":productInfoColor.value(forKey: "code"),
             "id":productInfoColor.value(forKey: "id"),
             "image":productInfoColor.value(forKey: "image"),
             "label":productInfoColor.value(forKey: "label"),
             "optionslabel":productInfoColor.value(forKey: "optionslabel"),
             "price":productInfoColor.value(forKey: "price"),
             "qty":productInfoColor.value(forKey: "qty")]],

         ["assoc_prodID":"92",
         "assoc_prodValue":currentSelectedColor,
         "productInfo":[
             "code":productInfoColor.value(forKey: "code"),
             "id":productInfoColor.value(forKey: "id"),
             "image":productInfoColor.value(forKey: "image"),
             "label":productInfoColor.value(forKey: "label"),
             "optionslabel":productInfoColor.value(forKey: "optionslabel"),
             "price":productInfoColor.value(forKey: "price"),
             "qty":productInfoColor.value(forKey: "qty")]]
                  ]

     "productData":productData,
     "qty":currentSelectedQuantity

] as NSDictionary
//saving object in objective c class


- (void)saveCartArray:(NSArray *)arrayToSave {

    NSMutableArray *archiveArray = [NSMutableArray arrayWithCapacity:arrayToSave.count];

    for (NSMutableDictionary* productDic in arrayToSave) {
        NSData *productDicData = [NSKeyedArchiver archivedDataWithRootObject:productDic];

        [archiveArray addObject:productDicData];
    }

    NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
    [userData setObject:archiveArray forKey:@"cart"];

}
//NSLOG of arrayToSave-

{
        "assoc_prod" =         (
                        {
                "assoc_prodID" = 92;
                "assoc_prodValue" = 396;
                code = "********.Code.color";
                id = 92;
                image = "********.Image.empty";
                label = "********.Label.color";
                optionslabel = Nude;
                price = "280.0000";
                qty = "0.0000";
            },
                        {
                "assoc_prodID" = 180;
                "assoc_prodValue" = 388;
                code = "********.Code.size";
                id = 180;
                image = "********.Image.empty";
                label = "********.Label.size";
                optionslabel = 36;
                price = "280.0000";
                qty = "0.0000";
            }
        );
        productData =         {
            additionalParameters =             (
            );
            associatedProd = "someData";
            brand = "";
            categoryId = 378;
            description = "";
            image = "http://www.x.com/xyz.jpg";
            link = "";
            linkDownloads = "";
            name = some;
            position = 0;
            price = 280;
            productId = 1421;
            qty = 0;
            set = 0;
            shortDescription = "";
            sku = some;
            type = some;
            wsp = "";
        };
        qty = 1;
    }
)

Willeke
  • 14,578
  • 4
  • 19
  • 47
  • ******** is my project name(target name is different) – ChaitanyaSoni96 Apr 23 '19 at 10:17
  • Your NSLog of arrayToSave seems to be Dictionary and not an array. It seems to be dicctionary with assoc_prod, productData and qty as 3 keys with corresponding values. But you are trying to treat it as an array. Please check that first. – Anand Apr 23 '19 at 10:50
  • Which class is `instance 0x280571380`? Are all objects (deep) inside the dictionaries compatible with `archivedDataWithRootObject:`? – Willeke Apr 23 '19 at 11:07
  • @Anand, in another method, the dictionary/past dictionaries passed saves into an array of dictionaries, then passes that array to this method. the NSLog is printed inside the for loop. – ChaitanyaSoni96 Apr 23 '19 at 12:20
  • @Willeke Im getting the crash in my objective C class, specifically in the line `code`NSData *productDicData = [NSKeyedArchiver archivedDataWithRootObject:productDic];`code` – ChaitanyaSoni96 Apr 23 '19 at 12:22
  • Possible duplicate of [-\[\_SwiftValue encodeWithCoder:\]: unrecognized selector sent to instance](https://stackoverflow.com/questions/39880459/swiftvalue-encodewithcoder-unrecognized-selector-sent-to-instance) – Willeke Apr 23 '19 at 12:43

1 Answers1

1

I have a hunch this is a similar problem I answered here: https://stackoverflow.com/a/53501401/5329717

Your case would be slightly different due to this:

- (void)saveCartArray:(NSArray *)arrayToSave {

    NSMutableArray *archiveArray = [NSMutableArray arrayWithCapacity:arrayToSave.count];

    for (NSMutableDictionary* productDic in arrayToSave) {
        NSData *productDicData = [NSKeyedArchiver archivedDataWithRootObject:productDic];

        [archiveArray addObject:productDicData];
    }

So essentially if I understand correctly the Swift bridged SwiftDeferredNSDictionary are elements in NSArray*. If you could extract

NSData *productDicData = [NSKeyedArchiver archivedDataWithRootObject:productDic];

to a separate method something like:

-(NSData*)dictionaryToData:(NSDictionary*)dic {
    return [NSKeyedArchiver archivedDataWithRootObject:productDic];
}

And use my linked answer workaround:

func mySwiftFunc(dic: Dictionary) {
     myObjcClassInstance.perform(#selector(NSSelectorFromString("dictionaryToData:"), with: dic as NSDictionary)
}

You could ensure you deal with "real" NSDictionary and avoid the implicit __SwiftValue bridging.

Kamil.S
  • 5,205
  • 2
  • 22
  • 51