Ios 如何防止自定义Swift应用跳回主屏幕?

Ios 如何防止自定义Swift应用跳回主屏幕?,ios,swift,arduino,homescreen,Ios,Swift,Arduino,Homescreen,嗨,知识渊博的人们 我正在用Swift写一个应用程序来控制我的车库门。该应用程序有4个按钮,用户可以从中选择。用户按下按钮后,只要连接到我的家庭局域网,应用程序就会通过传递JSON消息与Arduino(也在局域网上)通信。然后,Arduino启动继电器打开/关闭车门 在最初将应用程序部署到我的iPhone上后,它可以正常打开。但是,如果我几天不使用该应用程序,然后再次尝试打开它,而不是用4个按钮显示屏幕,它会跳回主屏幕。此外,如果我双击home(主页)按钮,我会看到正确的应用程序窗口,但如果我尝

嗨,知识渊博的人们

我正在用Swift写一个应用程序来控制我的车库门。该应用程序有4个按钮,用户可以从中选择。用户按下按钮后,只要连接到我的家庭局域网,应用程序就会通过传递JSON消息与Arduino(也在局域网上)通信。然后,Arduino启动继电器打开/关闭车门

在最初将应用程序部署到我的iPhone上后,它可以正常打开。但是,如果我几天不使用该应用程序,然后再次尝试打开它,而不是用4个按钮显示屏幕,它会跳回主屏幕。此外,如果我双击home(主页)按钮,我会看到正确的应用程序窗口,但如果我尝试将其置于前台,我将被迫再次返回主屏幕

我在下面写了我的代码,希望有人能指出我做错了什么?由于问题需要几天的时间才能显现出来,所以我还不能进行彻底的调试。所以,我很困惑。谢谢你的帮助

import UIKit

let INITIAL_STATE : Int = 0
var MADE_INITIAL_CONTACT : Int = 0
//let SETTINGS_FILENAME = "userSettings.plist"


class ViewController: UIViewController {

    @IBOutlet weak var leftOpenImage: UIImageView!
    @IBOutlet weak var leftClosedImage: UIImageView!
    @IBOutlet weak var rightOpenImage: UIImageView!
    @IBOutlet weak var rightClosedImage: UIImageView!

    var leftOpenLED = -1
    var leftClosedLED = -1
    var rightOpenLED = -1
    var rightClosedLED = -1
    var arduinoURL = "http://192.168.1.74"

    override func viewDidLoad() {
        super.viewDidLoad()

        // These routines below are all identical. They
        // make the UIImageView touch actionable. I found
        // a StackOverflow post that described how to do this for 
        // this version of Swift...God I hate Apple...and Swift


        let tgrLeftOpen = UITapGestureRecognizer(target: self, action: #selector(leftOpenImageTapped(tgrLeftOpen:)))
        leftOpenImage.isUserInteractionEnabled = true
        leftOpenImage.addGestureRecognizer(tgrLeftOpen)


        let tgrLeftClosed = UITapGestureRecognizer(target: self, action: #selector(leftClosedImageTapped(tgrLeftClosed:)))
        leftClosedImage.isUserInteractionEnabled = true
        leftClosedImage.addGestureRecognizer(tgrLeftClosed)


        let tgrRightOpen = UITapGestureRecognizer(target: self, action: #selector(rightOpenImageTapped(tgrRightOpen:)))
        rightOpenImage.isUserInteractionEnabled = true
        rightOpenImage.addGestureRecognizer(tgrRightOpen)


        let tgrRightClosed = UITapGestureRecognizer(target: self, action: #selector(rightClosedImageTapped(tgrRightClosed:)))
        rightClosedImage.isUserInteractionEnabled = true
        rightClosedImage.addGestureRecognizer(tgrRightClosed)


        // get initial door states from Arduino

        /*
        if (MADE_INITIAL_CONTACT == 0) {
            performRestCall()
            MADE_INITIAL_CONTACT = 1

            print("STILL IN HERE")
        }
        */

        performRestCall()
    }


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


    func leftOpenImageTapped(tgrLeftOpen: UITapGestureRecognizer) {
        // if left door closed, open it
        if (leftOpenLED == 0 && leftClosedLED == 1) {
            // change which images are highlighted
            leftOpenImage.image = UIImage(named: "open-25%")
            leftClosedImage.image = UIImage(named: "closed")
            print("You tapped the left door open button!")

            // update door state
            leftOpenLED = 1
            leftClosedLED = 0

            print("LeftOpenLED is now ")
            print(leftOpenLED)
            print("LeftClosedLED is now ")
            print(leftClosedLED)

            // create new JSON message to send to Arduino
            CreateJSONMessage()
        }
    }


    func leftClosedImageTapped(tgrLeftClosed: UITapGestureRecognizer) {
        // if left door open, close it
        if (leftOpenLED == 1 && leftClosedLED == 0) {
            // change which images are highlighted
            leftClosedImage.image = UIImage(named: "closed-25%")
            leftOpenImage.image = UIImage(named: "open")
            print("You tapped the left door closed button!")

            // update door state
            leftOpenLED = 0
            leftClosedLED = 1

            print("LeftOpenLED is now ")
            print(leftOpenLED)
            print("LeftClosedLED is now ")
            print(leftClosedLED)

            // create new JSON message to send to Arduino
            CreateJSONMessage()
        }
    }


    func rightOpenImageTapped(tgrRightOpen: UITapGestureRecognizer) {
        // if right door closed, open it
        if (rightOpenLED == 0 && rightClosedLED == 1) {
            // change which images are highlighted
            rightOpenImage.image = UIImage(named: "open-25%")
            rightClosedImage.image = UIImage(named: "closed")
            print("You tapped the right door open button!")

            // update door state
            rightOpenLED = 1
            rightClosedLED = 0

            print("rightOpenLED is now ")
            print(rightOpenLED)
            print("rightClosedLED is now ")
            print(rightClosedLED)

            // create new JSON message to send to Arduino
            CreateJSONMessage()
        }
    }


    func rightClosedImageTapped(tgrRightClosed: UITapGestureRecognizer) {
        // if right door open, close it
        if (rightOpenLED == 1 && rightClosedLED == 0) {
            // change which images are highlighted
            rightClosedImage.image = UIImage(named: "closed-25%")
            rightOpenImage.image = UIImage(named: "open")
            print("You tapped the right door closed button!")

            // update door state
            rightOpenLED = 0
            rightClosedLED = 1

            print("rightOpenLED is now ")
            print(rightOpenLED)
            print("rightClosedLED is now ")
            print(rightClosedLED)

            // create new JSON message to send to Arduino
            CreateJSONMessage()
        }
    }


    /*  performRestCall() simply takes the URL you provided to talk to the Arduino and sets up a background HTTP request using an Operation Queue. We utilize Swift closures to handle the results of the background web request.

     The code receives the results and calls handleResultsOfWebCall(_:) on the main thread which parses and displays the results.
     */
    func performRestCall() {

        let url = URL(string: arduinoURL)
        var request = URLRequest(url: url! as URL)
        request.httpMethod = "GET"
        request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData
        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")

        let session = URLSession.shared
        let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in

            guard error == nil else {
                print("Guard error")
                print(error!)
                return
            }
            guard let data = data else {
                print("Data is empty")
                return
            }

            //let json = try! JSONSerialization.jsonObject(with: data, options: [])
            //print(json)
            self.handleResultsOfWebCall(theData : data)
        })

        task.resume()
    }



    /* This parses the JSON information. This method checks to see if any data was returned, and then uses the built-in NSJSONSerialization handler to get the results into a NSDictionary object.

     */
    func handleResultsOfWebCall(theData : Data) {
        do {
            let jsonResults = try JSONSerialization.jsonObject(with: theData as Data, options:.allowFragments) as! [String:Any]

            self.leftOpenLED = jsonResults["leftOpenLED"] as! Int
            self.leftClosedLED = jsonResults["leftClosedLED"] as! Int
            self.rightOpenLED = jsonResults["rightOpenLED"] as! Int
            self.rightClosedLED = jsonResults["rightClosedLED"] as! Int

            //print("leftOpenLED = \(leftOpenLED)")
            //print("leftClosedLED = \(leftClosedLED)")
            //print("rightOpenLED = \(rightOpenLED)")
            //print("rightClosedLED = \(rightClosedLED)")

            if (leftOpenLED == 1 && leftClosedLED == 0) {
                // change which images are highlighted
                leftOpenImage.image = UIImage(named: "open-25%")
                leftClosedImage.image = UIImage(named: "closed")
            } else if (leftOpenLED == 0 && leftClosedLED == 1) {
                // change which images are highlighted
                leftOpenImage.image = UIImage(named: "open")
                leftClosedImage.image = UIImage(named: "closed-25%")
            }


            if (rightOpenLED == 1 && rightClosedLED == 0) {
                // change which images are highlighted
                rightOpenImage.image = UIImage(named: "open-25%")
                rightClosedImage.image = UIImage(named: "closed")
            } else if (rightOpenLED == 0 && rightClosedLED == 1) {
                // change which images are highlighted
                rightOpenImage.image = UIImage(named: "open")
                rightClosedImage.image = UIImage(named: "closed-25%")
            }


        } catch let error as NSError {
            print("JSON Error \(error.localizedDescription)")
            //showAlert(alertMessage: "Error retrieving results-check the URL or Server!")
        }
    }





    func CreateJSONMessage() {
        // Create a JSON message to send to Arduino
        // so it knows to update it's own local values
        // of parameters and then open/close doors as
        // necessary

        // define a JSON object to be a dictionary
        let jsonObject: NSMutableDictionary = NSMutableDictionary()

        // set values in dict
        jsonObject.setValue(leftOpenLED, forKey: "leftOpenLED")
        jsonObject.setValue(leftClosedLED, forKey: "leftClosedLED")
        jsonObject.setValue(rightOpenLED, forKey: "rightOpenLED")
        jsonObject.setValue(rightClosedLED, forKey: "rightClosedLED")
        //print("json object = \(jsonObject)")

        do {
            /*
            let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: JSONSerialization.WritingOptions()) as NSData
            let jsonString = NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue) as! String
            print("json string = \(jsonString)")
            */

            // create the url with NSURL
            let url = NSURL(string: arduinoURL)
            let request = NSMutableURLRequest(url: url! as URL)
            let session = URLSession.shared
            request.httpMethod = "POST"
            request.httpBody = try? JSONSerialization.data(withJSONObject: jsonObject, options: [])
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            request.addValue("application/json", forHTTPHeaderField: "Accept")

            let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
                print("Response: \(response)")})

            task.resume()
        } catch _ {
            print ("JSON Failure")
        }

    }
}

我认为您编写的代码没有问题。这就是iOS应用程序状态的维护方式

发生的情况是,如果应用程序有一段时间没有被使用,操作系统会将应用程序转换到暂停模式,在该模式下,应用程序的三个内存被释放

因此,在您的情况下,当您在一段时间后重新启动应用程序时,操作系统将其视为初始启动

我建议您阅读背景转换周期


这可能是一个评论,但有点长

我也希望看到您的AppDelegate,但我怀疑这只是默认设置

首先,由于您在CreateJSONMessage方法中使用的是
try?
而不是
try
,因此捕获不会起任何作用(并且应该生成警告)

问几个问题,看看这是否是一个生命周期的问题。 当你回到应用程序时(过了一段时间,它开始不正常运行),你看到你的启动屏幕了吗? 如果重新启动设备,我假设它的行为与预期的一样,会发生什么

若要查看它是否由于某个try块而崩溃,请更改try?要尝试,然后在每个捕获中,将错误写入应用程序中的文本视图

catch let error {
  // write error to some new "debug" text field. 
}

它跳到主屏幕的原因是因为它正在崩溃。你有崩溃日志吗?谢谢回复@jacobking。我没有任何崩溃日志。一旦我将应用程序部署到iPhone上,我不确定如何访问这些。你知道怎么做吗?你能做的最好的事情就是在你的手机连接到调试器时尝试重现崩溃。我怀疑这与一个有缺陷的生命周期有关。请帮我一个忙,把你的
AppDelegate.swift
文件添加到问题中,与此无关。基本上这与你的团队证书有关。我猜你不是苹果开发者计划的付费会员,在这种情况下,证书的有效期只有一周。每周重建并安装应用程序,让它继续工作或支付年费。哇,难以置信。谢谢@Azzaknight。所以我的下一个问题是,有没有一种方法可以不必为我的小应用程序每周不重新安装证书的情况下运行而支付99美元?我不打算将此发布到应用商店。只有我的姻亲和我自己。谢谢@Harsh的评论。我打算在工作的时候偷偷抽出一些时间来看看这件事。我甚至不知道这是一个“东西”,所以这肯定是一个新的尝试。关于
try?
生成警告,您是正确的。此外,当应用程序出现问题时,我返回到应用程序,我会立即看到启动屏幕,然后它会返回到iPhone的主屏幕。此外,当我重新启动设备时,问题仍然存在。这真让我困惑。关于
try?
try
以及在catch部分写入错误,我将提出您的其他建议。最后,关于AppDelegate文件,您也是正确的。这只是默认值。