1

I am writing a cordova plugin for HealthKit and my task is to make sure that we can dynamically read more or less data from HK. Im doing the native part in swift. But I mostly write JavaScript so I am a bit lost in with the Swift part.

I want to be able to dynamically invoke methods having only a string.

let store = HKHealthStore()

    do {
        let bloodType: HKBloodTypeObject = try store.bloodType()
...

That is an example to read blood type. I am not a Swift developer, but is there any way I can do this dynamically, like I would do in javascript:

... // assuming this function receives a string as paramater
let param[0] = try store[param[0]]() // <-- how to do this in Swift?

then i can talk to a server and get a list of characteristics and load them dynamically from healthkit without having to update my code and hardcode for each possible characteristic.

Elemenofi
  • 374
  • 5
  • 18

1 Answers1

0

Create a mapping from your parameter strings to an API enumeration.

enum API: String {
    case function1 = "function1"
    case function2 = "functionTwo"
    case function3 = "threethreethree"
}

Create a relay function that maps the API enumeration to the Swift function.

func callTheCorrectFunction(_ api: API) {
    switch api {
    case .function1: updateBlood()
    case .function2: spinAround()
    case .function3: jump()
    }
}

Construct your function call using enum's rawValue initializer.

let param = fromSomeJsonStrings[0]
let api = API(rawValue: param)
callTheCorrectFunction(api)

Alternatively, you could use a dictionary mapping from [String: Function] in much the same way.

typealias Function = () -> ()
let dict = {
    "function1": updateBlood,
    "function2": spinAround,
}
dict[param[0]]()
sdasdadas
  • 23,917
  • 20
  • 63
  • 148
  • Is there something I do not understand or in the end here you are also hardcoding updateBlood(), spinAround(), etc? – Elemenofi Feb 10 '17 at 15:09
  • I mean... you'll have to hardcode the method at some point. That's how you'll know what method to call. This is just introducing a mapping between strings and functions, though. – sdasdadas Feb 10 '17 at 15:11
  • i understand but then i am in the same problem. the thing is that as apple extends HKHealthStore i want to be able to read new properties dynamically without having to modify the plugin... so I need to be able to do HKHealthStore['somethingNew']() – Elemenofi Feb 10 '17 at 15:12
  • No, that solves your problem. Imagine you want to read the string "bio" from a JSON file and call the `biologicalSex()` function in the `HKHealthStore`. All you need, at the very lowest level, is a function that takes a string, performs an if statement (ie. if string == "bio"), and then calls `biologicalSex()`. I gave you a bit of a safer version but the idea is the same. – sdasdadas Feb 10 '17 at 15:25
  • Hey thanks for going deep with me in this but it does not solve my problem. I want the json file to send 'biologicalSex' not 'bio', because then i dont want a dictionary that i have to expand everytime healthkit expands... i want to get the string from the json and invoke a method whose name is that string. – Elemenofi Feb 10 '17 at 15:31
  • 1
    Ah, I understand. You're looking for "reflection" - for example, http://stackoverflow.com/questions/24245262/call-a-method-from-a-string-in-swift I'm not sure Swift's exact capabilities but hopefully that sets you in the right direction. – sdasdadas Feb 10 '17 at 15:40