Home > Mobile >  Cannot create var
Cannot create var

Time:02-21

I'm facing a problem with creating an variable. Here's an example what I've wanted to do:

I have JSON data in [ ]. I'm choosing smth in the picker and this changes pickerSelection1 and I can show in the view this string. Code is looking like this:

var cc1: String {
        guard api.currencyCode1.count > 0 else {
            return "err"
        }
        let cc1 = api.currencyCode1[pickerSelection1]
        return cc1
    }
    

Here's what I'm trying to do in the new project:

  var cc1: String {
        guard api.currencies.count > 0 else {
            return "err"
        }
        ForEach(api.currencies, id: \.self) { cc1 in // BUG: Static method 'buildBlock' requires that 'String.SubSequence' (aka 'Substring') conform to 'AccessibilityRotorContent'
            let cc1 = cc1.currencyCode[$pickerSelection1] // BUG: Subscript 'subscript(_:)' requires that 'Binding<Int>' conform to 'RangeExpression'
            cc1
        }
    }

I'm pretty sure I'm doing smth wrong and I'm not supposed to use : String { }. Need your advise, ladies and gentlemen.

P.S.: here's the whole code:

// Model
import Foundation

struct CurrencyModel: Codable {
    var results: [String:Double]
}

struct CurrencyNewModel: Codable {
    var currencies: [String:String]
}

struct Currency: Codable, Hashable {
    let currencyCode: String
    let fullName: String
    var price: Double
}
// ViewModel
import SwiftUI


class CurrencyViewModel: ObservableObject {
    
    @Published var currencies: [Currency] = []

          init() {
              fetchNewData { [self] (currency) in
                  switch currency {
                  case .success(let names):
                      print("Success")
                      DispatchQueue.main.async {
                          self.currencies = names.currencies.map {
                          Currency(currencyCode: $0.key, fullName: $0.value, price: 0)
                          }
                      }
                      fetchData { result in
                          switch result {
                          case .success(let prices):
                              print("Success")
                              
                   
                              for (index, value) in currencies.enumerated() {
                                  if let price = prices.results.first(where: { $0.key == value.currencyCode }) {
                                      DispatchQueue.main.async {
                                      currencies[index].price = price.value
                                        }
                                      }
                                  }
                          case .failure(let error):
                              print(error)
                          }
                      }
                  case .failure(let error):
                      print("Error", error)
        }
    }
}
      
     
    
   
    
func fetchData(completion: @escaping (Result<CurrencyModel,Error>) -> ()) {
    guard let url = URL(string: "https://api.fastforex.io/fetch-all?from=USD&api_key=7ffe65c2ef-926f01d9e8-r7eql2") else { return }
    URLSession.shared.dataTask(with: url) { data, responce, error in
        if let error = error {
            completion(.failure(error))
            return
        }
        
        guard let safeData = data else { return }
        
        do {
            let currency = try JSONDecoder().decode(CurrencyModel.self, from: safeData)
            completion(.success(currency))
        }
        catch {
            completion(.failure(error))
        }
    }
    .resume()
    
    
    }
    func fetchNewData(completion: @escaping (Result<CurrencyNewModel,Error>) -> ()) {
        guard let url = URL(string: "https://api.fastforex.io/currencies?api_key=7ffe65c2ef-926f01d9e8-r7eql2") else { return }
        URLSession.shared.dataTask(with: url) { data, responce, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let safeData = data else { return }
            
            do {
                let currency = try JSONDecoder().decode(CurrencyNewModel.self, from: safeData)
                completion(.success(currency))
            }
            catch {
                completion(.failure(error))
            }
        }
        .resume()
        
    }

} 
// View
import SwiftUI

struct CurrencyView: View {
    
    @StateObject var api = CurrencyViewModel()
    
    @State var pickerSelection1 = 1
    @State var pickerSelection2 = 1
    
    var body: some View {
        
        VStack {
            Picker("", selection: $pickerSelection1) {
            ForEach(api.currencies, id: \.self) { c1 in
                Text(c1.currencyCode   " "   c1.fullName)
                }
            }
            .id(UUID())
            .labelsHidden()
            
            Picker("", selection: $pickerSelection2) {
            ForEach(api.currencies, id: \.self) { c2 in
                Text(c2.currencyCode   " "   c2.fullName)
                }
            }
            .id(UUID())
            .labelsHidden()
            
            
        }
    }
    
    var cc1: String {
        guard api.currencies.count > 0 else {
            return "err"
        }
        ForEach(api.currencies, id: \.self) { cc1 in
            let cc1 = cc1.currencyCode[$pickerSelection1]
            cc1
        }
    }
}
    
struct CurrencyView_Previews: PreviewProvider {
    static var previews: some View {
        CurrencyView()
    }
}

CodePudding user response:

ForEach is only for returning Views

you should use

for cc1 in api.currencies{
    //The rest of your code
}

and use pickerSelection1 without the $

The other issue may be that the pickerSelection1 type does not match c1's type.

They should match or else the selection part of the operation will not work as you expect.

  • Related