我有一个应用程序,当我通过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上完美运行
答案 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()