1

I've got the following code, that runs in a playground. I'm attempting to allow subscript access to @Published variables in a class. The only way I've found so far to retrieve the String value in the below implementation of getStringValue is to use the debugDescription, and pull it out -- I've looked at the interface for Published, but can't find any way to retrieve the value in a func like getStringValue

Any pointers would be greatly appreciated :)

Edited to include an example of how it works with a non-published variable.

Cheers

import Foundation
import Combine

protocol PropertyReflectable {}

extension PropertyReflectable {
  subscript(key: String) -> Any? {
    return Mirror(reflecting: self).children.first { $0.label == key }?.value
  }
}

class Foo : PropertyReflectable {
  @Published var str: String = "bar"
  var str2: String = "bar2"
}

// it seems like there should be a way to get the Published value without using debugDescription
func getStringValue(_ obj: Combine.Published<String>?) -> String? {
  if obj == nil { return nil }
  let components = obj.debugDescription.components(separatedBy: "\"")
  return components[1]
}
let f = Foo()

let str = getStringValue(f["_str"] as? Published<String>)
print("got str: \(str!)")
// str == "bar" as expected
let str2 = f["str2"]!
print("got non-published string easily: \(str2)")
Kem Mason
  • 1,548
  • 17
  • 26
  • You can use .handleEvent or .sink – cora Oct 17 '22 at 00:31
  • I don't want an event or notification of changes to the str variable -- I just want to retrieve it in a synchronous method -- I don't think .handleEvent or .sink will work to replace the current getStringValue implementation, but if they can somehow, I'd love to hear more detail :). I've updated my question slightly to reflect that. – Kem Mason Oct 17 '22 at 03:05
  • Why are you using Published then? – cora Oct 17 '22 at 11:51
  • The @ Published event is being handled in another place, by other code -- so I do need the @ Published for other reasons. In this case, I'd like to be able to have f["str"] (or f["_str"]) work similarly to f["str2"] -- or basically implement the getStringValue without using a debugDescription. Seems like there's got to be a way to retrieve the actual value of the variable, I just don't see it. – Kem Mason Oct 17 '22 at 20:23
  • Have you considered using ‘CurrentValueObject’? – cora Oct 17 '22 at 21:15

1 Answers1

1

Published seems to be steeped in some compiler magic, for lack of a better wording, since it can only be used as a property wrapper inside classes.

That being said, would something like this work?

final class PublishedExtractor<T> {
    @Published var value: T
        
    init(_ wrapper: Published<T>) {
        _value = wrapper
    }
} 

func extractValue<T>(_ published: Published<T>) -> T {
    return PublishedExtractor(published).value
}
Bbrk24
  • 739
  • 6
  • 22