2

I had a list of variable name like this (BankHelper.swift):

static var va_1_atm =
"""
<ol>
    <li>Silahkan kunjungi ATM terdekat</li>
    <li>Pilih Menu <strong>Transaksi Lain</strong></li>
    <li>Pilih <strong>Pembayaran</strong></li>
    <li>Pilih <strong>Lain-lain</strong></li>
    <li>Pilih <strong>BRIVA</strong></li>
    <li>Masukkan Nomor Virtual Account, <strong>\(virtual_account)</strong></li>
    <li>Pilih <strong>Ya</strong></li>
    <li>Ambil bukti bayar Anda, selesai</li>
</ol>
"""

static var va_2_atm =
"""
<ol>
    <li>Silahkan kunjungi ATM terdekat</li>
    <li>Pilih Menu <strong>Transaksi Lain</strong></li>
    <li>Pilih <strong>Pembayaran</strong></li>
    <li>Pilih <strong>Lain-lain</strong></li>
    <li>Pilih <strong>BRIVA</strong></li>
    <li>Masukkan Nomor Virtual Account, <strong>\(virtual_account)</strong></li>
    <li>Pilih <strong>Ya</strong></li>
    <li>Ambil bukti bayar Anda, selesai</li>
</ol>
"""

static var va_3_atm =
"""
<ol>
    <li>Silahkan kunjungi ATM terdekat</li>
    <li>Pilih Menu <strong>Transaksi Lain</strong></li>
    <li>Pilih <strong>Pembayaran</strong></li>
    <li>Pilih <strong>Lain-lain</strong></li>
    <li>Pilih <strong>BRIVA</strong></li>
    <li>Masukkan Nomor Virtual Account, <strong>\(virtual_account)</strong></li>
    <li>Pilih <strong>Ya</strong></li>
    <li>Ambil bukti bayar Anda, selesai</li>
</ol>
"""

and I have value data that like this:

ReservationModel.bankAccount = 1

the question is how can I use the value above to dynamically change the variable name for the list above, I try like this:

cell.bankDesc.text = BankHelper.va_+(ReservationModel.bankAccount)+_atm.htmlToString

but it's not working in Swift. How can I achieve something like that? , so when the value is changed it dynamically changes to list data.

2
  • 3
    Swift is compiled, not interpreted so you can't create a variable name "on the fly". You will need to use an array or a dictionary. Commented Sep 5, 2018 at 11:46
  • Well, I suppose you can, doesn't meant you should. Commented Sep 6, 2018 at 19:28

2 Answers 2

3

Solution with Array

With continuous integer values, you can make them indexes of an Array.

class BankHelper {
    static var va_1_atm = "<a>les gorilles</a>"
    static var va_2_atm = "<div>in comedy</div>"
    static var va_3_atm = "<marquee>die sad</marquee>"
    
    fileprivate static var all = [va_1_atm, va_2_atm, va_3_atm]
    
    static func string(for bankAccount: Int) -> String? {
        return all[bankAccount - 1]
    }
}

Usage:

cell.bankDesc.text = BankHelper.string(for: ReservationModel.bankAccount)!.htmlToString

Solution with Dictionary

With discontinuous values, you can make them keys of a Dictionary.

class BankHelper {
    static var va_1_atm = "<a>les gorilles</a>"
    static var va_2_atm = "<div>in comedy</div>"
    static var va_3_atm = "<marquee>die sad</marquee>"
    
    fileprivate static var all = [1: va_1_atm, 2: va_2_atm, 3: va_3_atm]
    
    static func string(for bankAccount: Int) -> String? {
        return all[bankAccount]
    }
}

Usage:

cell.bankDesc.text = BankHelper.string(for: ReservationModel.bankAccount)!.htmlToString

Solution with Mirror

Alternatively, you may use mirroring to retrieve an instance variable by name (which means that your variables can't be static for this to work), but you may consider a singleton pattern.

class BankHelper {
    var va_1_atm = "<a>les gorilles</a>"
    var va_2_atm = "<div>in comedy</div>"
    var va_3_atm = "<marquee>die sad</marquee>"
    
    func string(for bankAccount: Int) -> String? {
        return Mirror(reflecting: self).descendant("va_\(bankAccount)_atm") as? String
    }
}

Usage:

cell.bankDesc.text = BankHelper().string(for: ReservationModel.bankAccount)!.htmlToString

Solution with NSObject

You need arbitrary access to static variables? Use a layer of Objective-C by conforming to NSObject.

class BankHelper: NSObject {
    @objc static var va_1_atm = "<a>les gorilles</a>"
    @objc static var va_2_atm = "<div>in comedy</div>"
    @objc static var va_3_atm = "<marquee>die sad</marquee>"
    
    static func string(for bankAccount: Int) -> String? {
        return value(forKey: "va_\(bankAccount)_atm") as? String
    }
}

Usage:

cell.bankDesc.text = BankHelper.string(for: ReservationModel.bankAccount)!.htmlToString
Sign up to request clarification or add additional context in comments.

2 Comments

Nice solutions, however those forced unwraps scream for crashes :)
@Cristik I only return optional values. Regarding Usage, well, I would never do what jchristsake is trying to do in the first place.
1

Why 3 different variables

static var va_1_atm
static var va_2_atm
static var va_3_atm

when we can use array here and use the value of ReservationModel.bankAccount to get to the index of the array to get appropriate text.

However if you want to do it in this way

What can be done is, store all your variables in an array. The indexes for the variables you store in that array will correspond to the index values you're trying to include in the variable name.

var atms = [typeOfAtmVarHere]()

Then keep on adding in this array whenever you have any of static var va_1_atm matching the index based on va_1_atm in var.

Lastly iterate through it and get it from the array on basis of ReservationModel.bankAccount as index

4 Comments

im sorry, but my company policy keep that way.
updated the answer if you want it to do with multiple variables.
@jchristsake, company policy disallows usage of array?
@jchristsake - quite strange, but I would like to know why using array is not allowed in your company policy ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.