Swift - 可选绑定不显示UIAlertController

时间:2015-02-17 15:46:24

标签: swift ios8 xcode6 uialertview optional

我创建了一个辅助函数,通过使用可选绑定来检查NSUserDefaults的值。我想在执行IBAction中的任何代码之前使用此函数来确认值存在。

    func checkProfile() {
    //optional binding to confirm that some strings (even empty string values), have been saved to user defaults. Will not face error when unwrapping the optionals on webView or MFMailComposer. Checking Title, FirstName, SecondName

    if let titleString: String = userDefaults.stringForKey("title") {
        //confirmed that there is a string value for titleString
        println("there is a string value for titleString \(titleString)")

        if let firstNameString: String = userDefaults.stringForKey("firstName") {
            //confirmed that there is a string value for firstName

            if let secondNameString: String = userDefaults.stringForKey("secondName") {
                //confirmed that there is a string value for secondName

            } else {
                //secondNameString missing, show alert
                var alert: UIAlertController = UIAlertController(title: "Profile data incomplete", message: "Please provide your 'Profile' data to continue.", preferredStyle: UIAlertControllerStyle.Alert)
                    alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {
                    //"action in" casts this closure as a type of UIAlertAction which is required by the addAction property.
                    action in self.navigationController?.popToRootViewControllerAnimated(true)
                    //"return" provides the -> Void return type, as not including would return a type of closure (above)
                    return
                }))
                self.presentViewController(alert, animated: true, completion: nil)
            }
        } else {
            //FirstNameString missing, show alert
            var alert: UIAlertController = UIAlertController(title: "Profile data incomplete", message: "Please provide your 'Profile' data to continue.", preferredStyle: UIAlertControllerStyle.Alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {
                //"action in" casts this closure as a type of UIAlertAction which is required by the addAction property.
                action in self.navigationController?.popToRootViewControllerAnimated(true)
                //"return" provides the -> Void return type, as not including would return a type of closure (above)
                return
            }))
            self.presentViewController(alert, animated: true, completion: nil)
        }
    } else {
        //titleString missing, show alert
        var alert: UIAlertController = UIAlertController(title: "Profile data incomplete", message: "Please provide your 'Profile' data to continue.", preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {
            //"action in" casts this closure as a type of UIAlertAction which is required by the addAction property.
            action in self.navigationController?.popToRootViewControllerAnimated(true)
            //"return" provides the -> Void return type, as not including would return a type of closure (above)
            return
        }))
        self.presentViewController(alert, animated: true, completion: nil)
    }
}

正如您所看到的,对3个存储的字符串值进行相当直接的检查,如果缺少任何字符串值,则会返回UIAlertController。

在IBAction开始时实现此功能(用户点击按钮)时,它会表现出一些奇怪的行为。

根据存储在NSUserDefaults中的无关值,IBAction将执行到另一个ViewController的segue;或者它将实现另一个类的实例,并执行将生成PDF文件的函数。

当设置值使IBAction最终执行segue时,我可以看到可选绑定按预期工作,如果3个存储值之一= nil(执行segue之前),则返回UIAlertView。

但是,当设置为生成PDF时,似乎完全忽略checkProfile()功能。 (甚至不会在任何时候打印到控制台)。

这导致运行时错误,因为我在解包可选值时发现nil {i}我想要检查checkProfile() - 是否有任何理由说明为什么这个函数在执行segue之前会正确运行,但是不是在实现类实例之前?我认为目前这种行为没有合理的理由。

由于

修改

以下是调用函数的IBAction:

@IBAction func claimButtonPressed(sender: AnyObject){
//Saves more values to userDefaualts
userDefaults.setObject(dateOfJourneyTextField.text, forKey: "dateOfJourney")


checkTickets()
checkProfile()

//if function to check the ticket type
if userDefaults.stringForKey("ticketType") != "Annual" {
    //calls the function to create the PDF prior to attempting to load the Mail Composer View where it will be an attachment
    let composePaperClaim = ComposePaperClaim()
    composePaperClaim.generatePDF(self)

    //loads MFMailComposeViewContoller...

} else {
    //Does not require PDF, perform Segue to take to the WebView
    performSegueWithIdentifier("showWebViewSegue", sender: self)
}

}

当我看到错误时,正在调用composePaperClaim.generatePDF(self),因为它试图解包我试图建立的userDefaults.stringForKey("title")!已经通过可选绑定获得了值。

1 个答案:

答案 0 :(得分:0)

您正在调用此checkProfile()函数,但对结果不执行任何操作。该函数应返回一个布尔值或其他东西,以防止调用函数继续进行。你将得到的是在呈现的视图控制器之上的一堆推送视图控制器,然后进入一些奇怪的状态。

目前,只要该类型不是年度类型,您将在checkProfile中调用PDF生成函数。这可能会在警报的顶部显示另一个视图控制器,您没有看到,然后您可能假设在checkProfile函数中检查的某个内容中存在值。