-1

I have a piece of code that works,

var loginFieldText = ""
if let wd = UIApplication.shared.delegate?.window
{
    let vc = wd!.rootViewController //Check
    if(vc is UINavigationController)
    {
        let viewControllers = (vc as! UINavigationController).viewControllers
        for obj in viewControllers {
            if let loginField = obj.value(forKey: "loginField")
            {
                if let loginText = (loginField as AnyObject).value(forKey: "text")
                {
                    loginFieldText = loginText as! String
                }
            }
        }
    }
}

but my problem is that I have a error message if I use that line:

if let loginField = obj.value(forKey: "loginField") 

Because it checks if there is a key "key" that doesn't exist in the view. How can I check first if that key exists before it crashes?

Error message:

valueForUndefinedKey:]: this class is not key value coding-compliant for the key loginField.'

For info, If I try to use the most logical following code:

let loginVC = obj as! LoginViewController 
let loginTF = loginVC.loginTextField  

=> I have an error message:

fatal error: file '/Users/OlostA/Desktop/Git/FormBox/formbox/Formbox/Planning/Formbox-Bridging-Header.h' has been modified since the precompiled header '/Users/OlostA/Library/Developer/Xcode/DerivedData/Formbox-fpnftywlyjuvvubjjzpknxxdyhul/Build/Intermediates.noindex/PrecompiledHeaders/Formbox-Bridging-Header-swift_7N984CYB20BK-clang_28VAG4OSP9DZS.pch' was built
note: please rebuild precompiled header '/Users/OlostA/Library/Developer/Xcode/DerivedData/Formbox-fpnftywlyjuvvubjjzpknxxdyhul/Build/Intermediates.noindex/PrecompiledHeaders/Formbox-Bridging-Header-swift_7N984CYB20BK-clang_28VAG4OSP9DZS.pch'
/Users/OlostA/Desktop/Git/FormBox/formbox/Formbox/Planning/Formbox-Bridging-Header.h:36:9: note: in file included from /Users/OlostA/Desktop/Git/FormBox/formbox/Formbox/Planning/Formbox-Bridging-Header.h:36:
#import "LoginViewController.h"
        ^
/Users/OlostA/Desktop/Git/FormBox/formbox/Formbox/LoginViewController.h:18:9: note: in file included from /Users/OlostA/Desktop/Git/FormBox/formbox/Formbox/LoginViewController.h:18:
#import "MainViewController.h"
        ^
/Users/OlostA/Desktop/Git/FormBox/formbox/Formbox/MainViewController.h:17:9: error: 'Formbox-Swift.h' file not found
#import "Formbox-Swift.h"
        ^
1 error generated.
<unknown>:0: error: failed to emit precompiled header '/Users/OlostA/Library/Developer/Xcode/DerivedData/Formbox-fpnftywlyjuvvubjjzpknxxdyhul/Build/Intermediates.noindex/PrecompiledHeaders/Formbox-Bridging-Header-swift_7N984CYB20BK-clang_28VAG4OSP9DZS.pch' for bridging header '/Users/OlostA/Desktop/Git/FormBox/formbox/Formbox/Planning/Formbox-Bridging-Header.h'
ΩlostA
  • 2,501
  • 5
  • 27
  • 63
  • https://stackoverflow.com/questions/35398909/how-to-check-if-an-object-has-a-stored-property ? But why do you do this exactly? – Larme Nov 08 '17 at 14:22
  • @Larme Because I am in a viewcontroller that is a swift Class, and I tried to access to the value of a textView in a viewcontroller that is a objective-c Class. I didn't find another way than this... – ΩlostA Nov 08 '17 at 14:27
  • @Larme For info, I have a message error uiviewcontroller has no member "respondsToSelector" with the code : obj.respondsToSelector(Selector("loginField")) – ΩlostA Nov 08 '17 at 14:44
  • Yeah, this is old Swift, the new version: https://stackoverflow.com/questions/39818001/using-selector-in-swift-3 – Larme Nov 08 '17 at 14:47
  • I think if you checked the Viewcontroller you want like that if obj is LoginViewController{ let loginVC = obj as! LoginViewController ; let loginTF = loginVC.loginTextField} – Hosny Nov 08 '17 at 15:01
  • @Hosny, the problem, is that I cannot use "as! LoginViewController " It generates an error. I don't know why... I cannot add the #import LoginViewController in my bridge. – ΩlostA Nov 08 '17 at 15:05
  • What is the error ? – Hosny Nov 08 '17 at 15:09
  • @Hosny, I updated my ticket with the error message – ΩlostA Nov 08 '17 at 15:13
  • LoginViewController is Objective-C and use it in Swift Project , right ? – Hosny Nov 08 '17 at 15:16
  • Why do you first checks if `vc is UINavigationController` and then force cast it to `UINavigationController`? Also your error message in the bottom says that Derived Data is faulty and needs to be cleaned. – user28434'mstep Nov 08 '17 at 15:19
  • 1
    The suggestion *please rebuild precompiled header* is not an option? – vadian Nov 08 '17 at 15:21
  • @Hosny yep exaclty – ΩlostA Nov 08 '17 at 15:29
  • @Vadian, what do you mean ? – ΩlostA Nov 08 '17 at 15:31
  • @user28434 I delete that folder all ten minutes... – ΩlostA Nov 08 '17 at 15:31
  • I mean https://stackoverflow.com/questions/14793329/fixing-file-project-pch-has-been-modified-since-the-precompiled-header-was-bui – vadian Nov 08 '17 at 15:36
  • I think you didn't add the bridge header file correctly – Hosny Nov 08 '17 at 15:37

1 Answers1

0

First off go to the product menu and press the option key. That will change the menu option Clean to Clean Build Folder… That should solve the build error you've been seeing.

Make sure LoginViewController.h is included in the bridging header (looks like it is but better safe than sorry).

Then let's clean up that pyramid of doom you got going on there (don't worry, we have all written at least a few of them):

var loginFieldText = ""
// Check if the root view controller of the window is a navigation controller and grab a reference if it is.
guard let vc = UIApplication.shared.delegate?.window.rootViewController as? UINavigationController else { return }
let viewControllers = vc.viewControllers
for obj in viewControllers {
    // See if the obj can be cast as a LoginViewController and if the loginField can be retrieved
    guard let loginField = (obj as? LoginViewController)?.loginField else { continue }
    // We want loginFieldText to be an empty string or the contents of loginField so we use the nil-coalescing operator
    loginFieldText = loginField.text ?? loginFieldText
}

I wrote this without a compiler so there may be a little cleanup but the idea is there.

theMikeSwan
  • 4,739
  • 2
  • 31
  • 44