How to setup and fetched Strings Array in CoreData?

I have a method which need an Array of Strings for further calculations. For now I set up this array through UserDefaults, because it should store small (3-characters string) amount of data:

func setRow(for currency: Currency, in currencies: [Currency]) {

     // initialise array from UserDefaults
    var currencyRowsArray = UserDefaults.standard.stringArray(forKey: "currencyRowsArray") ?? [String]()
    
    // calculations with the array (add or remove string object to\from it
    if currency.isForConverter {
        currencyRowsArray.append(currency.shortName!)
    } else {
        guard let row = currencyRowsArray.firstIndex(of: currency.shortName!) else { return }
        currencyRowsArray.remove(at: row)
        currency.rowForConverter = 0
    }
    
    for (row, object) in currencyRowsArray.enumerated() {
        for currency in currencies {
            if object == currency.shortName {
                currency.rowForConverter = Int32(row)
            }
        }
    }

   // save array back to UserDefaults after calculations
    UserDefaults.standard.set(currencyRowsArray, forKey: "currencyRowsArray")
}

But since I have a CoreData implemented also I decided to store it in CoreData rather than UserDefaults. Here is how I tried to implement that:

1.I have entity Currency, so I created an attribute currencyRowsArray: Type - Transformable, Custom Class - [String], Transformer - NSSecureUnarchiveFromData, Optional - YES (because I don't need it to initialize every time a created a Currency object with other attributes)

2.In the setRow method:

let request: NSFetchRequest<Currency> = Currency.fetchRequest()
request.predicate = NSPredicate(format: "currencyRowsArray IN %@", currencyRowsArray)

3.Initialize the empty array to fill it later with fetched Data:

currencyRowsArray = [String]()

4.Fetch the array:

 do {
        let fetchResult = try context.fetch(request)
        currencyRowsArray = fetchedResult as! [String]
    } catch {
        print(error)
    }

5.After calculations save the changes:

do {
    try context.save()
} catch {
    print(error)
}

Full changed code of the setRow method:

func setRow(for currency: Currency, in currencies: [Currency]) {
    var currencyRowsArray = [String] ()
    
    let request: NSFetchRequest<Currency> = Currency.fetchRequest()
    request.predicate = NSPredicate(format: "currencyRowsArray IN %@", currencyRowsArray)
    
    do {
        let fetchResult = try context.fetch(request)
        currencyRowsArray = fetchResult as! [String]
    } catch {
        print(error)
    }
    
    if currency.isForConverter {
        currencyRowsArray.append(currency.shortName!)
    } else {
        guard let row = currencyRowsArray.firstIndex(of: currency.shortName!) else { return }
        currencyRowsArray.remove(at: row)
        currency.rowForConverter = 0
    }
    
    for (row, object) in currencyRowsArray.enumerated() {
        for currency in currencies {
            if object == currency.shortName {
                currency.rowForConverter = Int32(row)
            }
        }
    }
    
    do {
        try context.save()
    } catch {
        print(error)
    }
}

But every time the array loads as empty and when I make change, array doesn't add or remove items in it. What I did wrong?

Answered by Claude31 in 704647022

Check currencyRowsArray before save.context. I would suspect it is not yet updated.

    print(currencyRowsArray)
    do {
        try context.save()
    } catch {
        print(error)
    }
Accepted Answer

Check currencyRowsArray before save.context. I would suspect it is not yet updated.

    print(currencyRowsArray)
    do {
        try context.save()
    } catch {
        print(error)
    }
How to setup and fetched Strings Array in CoreData?
 
 
Q