adhoc分发时应用程序崩溃,但在使用XCode安装时不会崩溃

时间:2016-11-07 11:13:33

标签: ios swift xcode crash-reports

我有一个应用程序,当我通过itunes / Diawi adhoc发行版安装应用程序时,它会崩溃,但是当我通过XCODE安装应用程序时不会崩溃。

MY CRASH REPORT ..

Thread 0 Crashed:
0   Vabo                            0x00000001000bb07c specialized AppDelegate.registerDeviceForPushNotification(UIApplication) -> () (AppDelegate.swift:214)
1   Vabo                            0x00000001000ab260 ViewController.(connectToWebWith(String, password : String) -> ()).(closure #2).(closure #3) (ViewController.swift:265)
  

碰撞编号1的Swift方法:

func registerDeviceForPushNotification(application:UIApplication) -> Void {

        let settings: UIUserNotificationSettings = UIUserNotificationSettings.init(forTypes: [.Alert,.Badge,.Sound], categories: nil)
        self.pushNotificationToken = FIRInstanceID.instanceID().token()!
        let userID = self.userData["id"] as! NSNumber

        print("InstanceID token: \(self.pushNotificationToken)")
        self.registerDeviceOnServerWith(self.pushNotificationToken, userID: userID)
        application.registerUserNotificationSettings(settings)
        application.registerForRemoteNotifications()
    }


func registerDeviceOnServerWith(token:String, userID:NSNumber) -> Void {
        let params = ["api_token":token, "user_id":userID , "type":"iOS"]

        //        params.setValue(username, forKey: "email")
        //        params.setValue(password, forKey: "password")
        let urlString = Constants.kMainURL + Constants.kRegisterDeviceToken;
        let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
        let session = NSURLSession.sharedSession()
        request.HTTPMethod = "POST"

        do {
            request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)
        } catch {


            //handle error. Probably return or mark function as throws
            print(error)
            return
        }
        request.addValue(self.tokenID as String, forHTTPHeaderField: "token")
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
            // handle error
            guard error == nil else {

                return
            }

            print("Response: \(response)")
            let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
            print("Body: \(strData)")

            let json: NSDictionary?
            do {
                json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
            } catch let dataError {
                // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
                print(dataError)
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Error could not parse JSON: '\(jsonStr)'")
                // return or throw?
                return
            }

            // The JSONObjectWithData constructor didn't return an error. But, we should still
            // check and make sure that json has a value using optional binding.
            if let parseJSON = json {
                // Okay, the parsedJSON is here, let's get the value for 'success' out of it
                let success:NSString = (parseJSON["status"] as? NSString)!
                if success.isEqualToString("Success"){
                    print("APNS is Registeration is : \(success)")


                }else{

                    self.registerDeviceOnServerWith(token, userID: userID)
                    // Status Failed

                }

            }
            else {
                // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?

            }

        })

        task.resume()
    }

崩溃方法2:

func connectToWebWith(username:String, password:String) -> Void {
        self.startLoadingAnimator()
        let params = ["email":username, "password":password]

//        params.setValue(username, forKey: "email")
//        params.setValue(password, forKey: "password")
        let urlString = Constants.kMainURL + Constants.kSignInURL;
        let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
        let session = NSURLSession.sharedSession()
        request.HTTPMethod = "POST"

        do {
            request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)
        } catch {


            dispatch_async(dispatch_get_main_queue(), {
                self.stopLoadingAnimator()
                let alertView = UIAlertView.init(title: "Error", message: "Failed to authenticate", delegate: nil, cancelButtonTitle: "OK")
                alertView.show()


            })
            //handle error. Probably return or mark function as throws
            print(error)
            return
        }
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
            // handle error
            guard error == nil else {

                dispatch_async(dispatch_get_main_queue(), {

                    self.stopLoadingAnimator()
                    let alertView = UIAlertView.init(title: "Error", message: "Couldn't establish connection", delegate: nil, cancelButtonTitle: "OK")
                    alertView.show()


                })
                return
            }

            print("Response: \(response)")

            let json: NSDictionary?
            do {
                json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
            } catch let dataError {
                // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
                print(dataError)
                dispatch_async(dispatch_get_main_queue(), {

                    self.stopLoadingAnimator()
                    let alertView = UIAlertView.init(title: "Error", message: "Failed to authenticate", delegate: nil, cancelButtonTitle: "OK")
                    alertView.show()


                })
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Error could not parse JSON: '\(jsonStr)'")
                // return or throw?
                return
            }

            self.stopLoadingAnimator()
            // The JSONObjectWithData constructor didn't return an error. But, we should still
            // check and make sure that json has a value using optional binding.
            if let parseJSON = json {
                print("JSON = \(parseJSON)")
                // Okay, the parsedJSON is here, let's get the value for 'success' out of it
                let success:NSString = (parseJSON["status"] as? NSString)!
                if success.isEqualToString("Success"){
                    print("Succes: \(success)")
                    dispatch_async(dispatch_get_main_queue(), {

                            let userDefault = NSUserDefaults.standardUserDefaults()
                            userDefault.setValue(username, forKey: Constants.kVaboEmail)
                            userDefault.synchronize()
                            userDefault.setValue(password, forKey: Constants.kVaboPassword)
                            userDefault.synchronize()
                            userDefault.setBool(true, forKey: Constants.kIsLoggedIn)
                            userDefault.synchronize()
                            let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
                            appDelegate.tokenID = (parseJSON["token"] as? NSString)!
                            let array = parseJSON["userData"] as! NSArray
                            appDelegate.userData = array.objectAtIndex(0) as! NSDictionary
                            appDelegate.userDidLoggedIn()


                    })
                }else{
                    let errorString = parseJSON["messageData"] as! String
                    dispatch_async(dispatch_get_main_queue(), {
                        let alertView = UIAlertView.init(title: "Vabo", message: errorString, delegate: nil, cancelButtonTitle: "Dismiss")
                        alertView.show()

                    })


                }

            }
            else {
                // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Error could not parse JSON: \(jsonStr)")
                dispatch_async(dispatch_get_main_queue(), {

                    self.stopLoadingAnimator()
                    let alertView = UIAlertView.init(title: "Error", message: "Server Response Failed", delegate: nil, cancelButtonTitle: "OK")
                    alertView.show()


                })
            }

        })

        task.resume()
    }
  

P.S   应用程序上的iPhone崩溃有iOS 10.1,   虽然它在iOS 9.3.5上完美运行

1 个答案:

答案 0 :(得分:0)

从您提供的日志中,不清楚哪一行是第214行。 (AppDelegate.swift:214)并且日志中也缺少崩溃的原因。

但我发现你使用强制转换几个地方,当你试图访问它们时,我会确保这些值确实存在。我建议使用保护语句而不是强制转换:

func registerDeviceForPushNotification(application:UIApplication) -> Void {

   let settings: UIUserNotificationSettings = UIUserNotificationSettings.init(forTypes: [.Alert,.Badge,.Sound], categories: nil)

   guard let token = FIRInstanceID.instanceID().token(), let userID = self.userData["id"] as? NSNumber {
    // You might want to log something here
    return
   }

   print("InstanceID token: \(self.pushNotificationToken)")
   self.registerDeviceOnServerWith(self.pushNotificationToken, userID: userID)
   application.registerUserNotificationSettings(settings)
   application.registerForRemoteNotifications()
}

<强>更新

如果您查看UIUserNotificationSettings的文档,您可以看到它已在iOS 10中弃用。您应该在iOS 10上使用UNUserNotificationCenter:

let center = UNUserNotificationCenter.currentNotificationCenter()
center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
        // Enable or disable features based on authorization.
    }
application.registerForRemoteNotifications()

您可以找到更多信息herehere