0

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?

artexhibit
  • 198
  • 3
  • 17
  • 1
    If you use Core Data then make of its functionality properly. Don’t store the array as an attribute but instead store each currency as an instance of Currency with an attribute currencyCode (String). Another option here is to store the array of currencies as json to a file. – Joakim Danielson Feb 13 '22 at 09:32
  • Hi Joakim, thank you for the reply. Yes, and I have it already. This array I want to store is needed only for my calculations inside setRow method. This is why I need to store it too, but can't figure out how to initialize and save changes properly like I have now with UserDefaults case... – artexhibit Feb 13 '22 at 09:35
  • If you already store each currency then you don’t need to store an array, use a fetch request to get all currencies. Also see the update to my previous comment – Joakim Danielson Feb 13 '22 at 09:37
  • @JoakimDanielson, thank you. Any chance you can prepare some sample answer for me to implement storing an array of Strings in json? – artexhibit Feb 13 '22 at 09:41
  • You can always use google, https://stackoverflow.com/questions/28768015/how-to-save-an-array-as-a-json-file-in-swift – Joakim Danielson Feb 13 '22 at 09:48

0 Answers0