title: Why do iOS keychain values not change without leaving the ViewController?
body: <p>I have <a href="https://github.com/calvin-fisher/MonoTouchTools/blob/master/Keychain.cs" rel="nofollow">an abstraction on the iOS Keychain API</a> that seems to work well.  Basically, it has:</p>
  
  <pre><code>public string GetGenericPasswordField(string account)
  {
      var record = SecKeyChain.QueryAsRecord(query, out code);
      if (code == SecStatusCode.ItemNotFound)
          return null;
      return NSString.FromData(record.ValueData, NSStringEncoding.UTF8);
  }
  
  public void SetGenericPasswordField(string account, string value)
  {
      if (value == null)
      {
          SecKeyChain.Remove(record);
          return;
      }
      var record = new SecRecord (SecKind.GenericPassword) {
          Service = service,
          Label = label,
          Account = account,
          ValueData = NSData.FromString (value),
      };
      SecStatusCode code = SecKeyChain.Add (record);
      if (code == SecStatusCode.DuplicateItem)
      {
          // (remove and re-add item)
      }
  }
  </code></pre>
  
  <p>I have used this abstraction on my app's settings screen to save values while leaving, and then load those values elsewhere in the app.</p>
  
  <p>But I've run into an issue where saving a value does not appear to take effect if you don't leave the current ViewController.  What I'm doing is analogous to:</p>
  
  <pre><code>if (Keychain.GetGenericPasswordField("RemoteLogin") == null)
  {
      var remotePassword = GetFromDialog();
      Keychain.SetGenericPasswordField("RemoteLogin", Hash(remotePassword));
      // Safe to assume the RemoteLogin password got saved, right?
  }
  
  // Later on...
  
  if (Keychain.GetGenericPasswordField("RemoteLogin") == null)
  {
      // This block is being executed
  }
  </code></pre>
  
  <p>I've stepped through the code in the debugger to confirm that things are as I'm describing them, and that my abstraction method really is getting a <code>SecStatusCode.ItemNotFound</code> back, meaning null is the appropriate value to return.</p>
  
  <p>I worked around this once by moving the first half of my code back to a previous ViewController, and for some reason that seemed to wake it up, or clear out whatever caching is taking place.  But now I've encountered another situation where that's not really practical.</p>
  
  <p>Why is this happening?  Is my abstraction leaking?</p>