Hi
I have a custom UIView contained xib which is in an xcframework. The view has a timeout property which removes itself from the super view if it expiries.
If the view does expiry, it fires a delegate which the function can observe using the KVC approach.
What I'm experiencing is my function adds the view to the view controller ok, but doesn't display it until the function completes or throws an error.
Here is a snippet of what I have described:
// MARK: Contained in custom xcframework
class MyView: UIView {
var delegate: VerificationHandler?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
func initialize() {
let bundle = Bundle(for: type(of: self))
let uvNib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
let uvView = uvNib.instantiate(withOwner: self, options: nil).first as! UIView
addSubview(uvView)
Timer.scheduledTimer(withTimeInterval: TimeInterval(10), repeats: false) { [self] timer in
timer.invalidate()
delegate?.verification(didContinue: false)
removeFromSuperview()
}
}
}
protocol VerificationHandler {
func verification(didContinue: Bool)
}
class VerificationResult: NSObject {
@objc dynamic var value: Bool
init(_ value: Bool) {
self.value = value
}
}
public enum MyEnum {
}
public extension MyEnum {
private static var verificationResult: VerificationResult = VerificationResult(false)
public static func myFunction(_ viewController: UIViewController) throws -> MyObject {
if let viewController = viewController {
let view = MyView(frame: viewController.view.frame)
view.delegate = self as? VerificationHandler
viewController.view.addSubview(view)
let semaphore = DispatchSemaphore.init(value: 0)
// observe the change occurring in the view which creates the verificationResult.
var result: Bool
let kvc = verificationResult.observe(\.value, options: .new) { _, change in
result = change.newValue! // didContinue
semaphore.signal()
}
semaphore.wait()
if !result {
throw MyError.timeout
}
return MyObject(...)
}
}
extension MyEnum: VerificationHandler {
func verification(didContinue: Bool) {
MyEnum.verificationResult = VerificationResult(didContinue)
}
}
// MARK: View controller app code
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func onClick(_ sender: UIButton) {
do {
// this call is where the custom view from the xcframework should appear
let result = try MyEnum.myFunction(self)
}
catch let error {
print(error.localizedDescription)
}
}
}
I'm using the semaphore to wait for the timer in MyView to fire which would cause the KVC to invoke. Not sure if this is the best way, but I'm blocked and can't figure out why the view only appears after an Error is thrown from myFunc.
Any guidance appreciated.