简体   繁体   中英

I want to observe when a value has been changed, and to load the view

//Patient class
import Foundation

struct Patients {
    var family: NSArray
    var given: NSArray
    var id: String
    var birthdate:String
    var gender: String
}

struct Address {
    var city: String
    var country: String
    var line: NSArray
}

class Patient  {
     var flag = 0
    var address = Address(city: "", country: "", line: [""])
    var patient_info = Patients(family: [""], given: [""], id: "", birthdate: "", gender: "")
    var response : AnyObject?


    init(response: AnyObject) {
        self.response = response


        if let entry = response.objectForKey("entry") {
            //MARK: Address
            if let resource = entry[0].objectForKey("resource") {
                if let add = resource.objectForKey("address") {
                    address.city   =  add[0].objectForKey("city")! as! String
                    address.country =  add[0].objectForKey("country")! as! String
                    address.line = add[0].objectForKey("line")! as! NSArray
                    //MARK: patient

                    patient_info.birthdate = resource.objectForKey("birthDate")! as! String
                    patient_info.gender = resource.objectForKey("gender")! as! String
                    if let  name = resource.objectForKey("name") {
                        patient_info.family = name[0].objectForKey("family")! as! NSArray
                        patient_info.given = name[0].objectForKey("given")! as! NSArray
                    }
                }
            }
            //MARK: id
            if let link = entry[0].objectForKey("link") {
                if let url = link[0].objectForKey("url") {
                    let id = url.componentsSeparatedByString("/")
                    patient_info.id = id[id.count-1]

                }
            }
        }
  print(patient_info)
    }



}

//ViewController class

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {
    var viewModel = ViewModel()
    @IBOutlet weak var family_name: UITextField!
    @IBOutlet weak var given_name: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        family_name.delegate = self
        given_name.delegate = self

    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func textFieldShouldReturn(textField: UITextField) -> Bool {
        switch textField {

        case family_name:
            family_name.resignFirstResponder()
            given_name.becomeFirstResponder()

        case given_name:
            given_name .resignFirstResponder()

        default:
            print("")

        }

    return true

    }

    @IBAction func search(sender: UIButton) {
       let family_name1 = family_name.text!
        let given_name1 = given_name.text!
        viewModel .searchForPatient(family_name1, given_name: given_name1)
    //When the name property from my patient class changed I can call the //below method. How to implement the observer? 
  performSegueWithIdentifier("showSegue", sender:sender) 
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender:AnyObject?){
        if segue.identifier == "showPatientSegue" {
            if let displayViewController = segue.destinationViewController as? DisplayViewController {
                displayViewController.viewModelDisplay.patient = viewModel.patient

            }

        }



    }
}

// ViewModel where I make the request.
import Foundation
import Alamofire
import SystemConfiguration
class ViewModel {
    var patient = Patient!()


    func searchForPatient(family_name:  String, given_name : String) {
       let header = ["Accept" : "application/json"]
        Alamofire.request(.GET, "https://open-ic.epic.com/FHIR/api/FHIR/DSTU2/Patient?family=\(family_name)&given=\(given_name)", headers: header).responseJSON { response in
            self.patient = Patient(response: response.result.value!)

        }
    }



    func checkInternetConnection() -> Bool {

        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)
        let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
            SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
        }
        var flags = SCNetworkReachabilityFlags()
        if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
            return false
        }
        let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
        let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
        return (isReachable && !needsConnection)
    }
}

The problem is that the view loads fester than the request and I need to observe when a property has been changed in my Patient class, so the view can be loaded. If the view loads faster than the request I can't display the Patient information which I need.

You have lots options:

  1. Store a delegate (weak!) object to the ViewController so that when your patient finishes, you can load the view. In the meantime, display something sensible in the view instead.

  2. Send an NSNotification out, which the ViewController is a listener for.

  3. KVO (Explanation of it here , just search for 'key-value observing'), which would require your Patient object to extend NSObject so that you can leverage objc's KVO.

Hope that helps!

You can add an observer on your variable this way :

var yourVariable:String!{
    didSet{
        refreshView()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM