I'm trying to use TwitterKit framework for my iOS app (in Swift). But when I use Twitter.sharedInstance().APIClient, it occurs an error saying fatal error: unexpectedly found nil while unwrapping an Optional value.
Here is my code:
import TwitterKit
func getUserInfo () {
let twUserID = "my twitter user_id" // This is not nil
let client = Twitter.sharedInstance() // This is not nil
let apiClient = Twitter.sharedInstance().APIClient // This is nil
// This occurs an error
// fatal error: unexpectedly found nil while unwrapping an Optional value
Twitter.sharedInstance().APIClient.loadUserWithID (twUserID, completion: {
(user, error) in
if let validUser = user {
println("Success!")
}
else {
println("Failed...")
}
})
}
Any help?
Even on old Objective-C frameworks that haven't been updated with nullability attributes, you can use Optional binding to ensure that force-unwrapped Optionals have a value before using them.
In the example listed above, you can optionally bind to the value of Twitter.sharedInstance().APIClient, like this:
if let apiClient = Twitter.sharedInstance().APIClient {
apiClient.loadUserWithID (twUserID, completion: {
(user, error) in
if let validUser = user {
println("Success!")
}
else {
println("Failed...")
}
})
}
Related
I am trying to create reminder according to this tutorial, trying to change the Swift 1 to Swift 2 code:
http://www.techotopia.com/index.php/Using_iOS_8_Event_Kit_and_Swift_to_Create_Date_and_Location_Based_Reminders
I get the error: Value for optional type not unwrapped.
func createReminder() {
if (appDelegate!.eventStore != nil) {
let reminder = EKReminder(eventStore: appDelegate!.eventStore) //value not unwrapped
reminder.title = reminderText.text
reminder.calendar =
appDelegate!.eventStore!.defaultCalendarForNewReminders()
let date = myDatePicker.date
let alarm = EKAlarm(absoluteDate: date)
reminder.addAlarm(alarm)
var error: NSError?
appDelegate!.eventStore!.saveReminder(reminder,
commit: true, error: &error)
if error != nil {
print("Reminder failed with error \(error?.localizedDescription)")
}
}
}
I understand the concept of optional value (variable can be not assigned a value at this point during run time), what I do not understand is that I am inside the if block, that checks the value for not being nil. Therefore appDelegate!.eventStore is not nil in this block, therefore does not need to be unwrapped (?).
I also tried setting the "!" after this variable, like this:
appDelegate!.eventStore!
but it breaks other code, it gives error around this code:
appDelegate!.eventStore!.saveReminder(reminder,
commit: true, error: &error) //extra argumenr 'error' in call
Surrounding it with do{}catch{} statement does not help..
By the looks of it, this is more to do with the extra argument than with the implicitly unwrapped optional — Apple have updated a lot of their SDK for Swift 2, to avoid passing in the reference to the NSError object and use try instead.
eventStore.saveReminder(reminder, commit: true, error: &error)
becomes
do {
try eventStore.saveReminder(reminder, commit: true)
}
catch error: NSError {
print(error.localizedDescription)
}
As a general rule, I avoid implicitly unwrapped optionals like the plague — there is very little need for them and when they do exist you can always make a proper non-optional. Try:
func createReminder() throws {
guard let eventStore = appDelegate?.eventStore else {
let error: NSError = NSError(domain: "com.mycompany.myapp", code: 1, userInfo: [
NSLocalizedDescriptionKey: "Unable to get event store from app delegate"
])
throw error
}
let reminder = EKReminder(eventStore: eventStore)
reminder.title = reminderText.text
reminder.calendar = eventStore.defaultCalendarForNewReminders()
let date = myDatePicker.date
let alarm = EKAlarm(absoluteDate: date)
reminder.addAlarm(alarm)
try eventStore.saveReminder(reminder, commit: true)
}
That way you are not playing around with implicitly unwrapped optionals, eventStore is guaranteed to be set when you use it and whatever calls createReminder() can handle the error is there is one (you would probably also throw an error instead of printing out if the eventStore is not set).
Ok, I am not sure about the code, but I fixed the errors, I needed to still use the do-try-catch, but like so:
do {
try appDelegate!.eventStore!.saveReminder(reminder, commit: true)
} catch {
print(error)
}
if you check an optional value for nil
if (appDelegate!.eventStore != nil) {
you have to unwrap it in case it's not nil
let reminder = EKReminder(eventStore: appDelegate!.eventStore!)
A more suitable way is to use optional bindings
if let store = appDelegate!.eventStore {
let reminder = EKReminder(eventStore: store)
…
}
What is the purpose to declare appDelegate as optional?
The AppDelegate class exists in any application by default and could be never nil.
The code below is giving me the error " 'AnyObject' is not convertible to 'String' " at the line where I put my "if let" statement to unwrap the optional productData pulled from Parse. I'm just trying to pull a String from an object in Parse. I've checked everywhere and all the standard answers/solutions aren't working. Any thoughts?
Most of this code is taken straight from the Parse iOS docs Here
import Foundation
import Parse
func getDataFromParse () {
var productDataFromParse = PFQuery(className:"Product")
productDataFromParse.getObjectInBackgroundWithId("uyeXHufDgq") {
(productData: PFObject?, error: NSError?) -> Void in
if error == nil && productData != nil {
if let productTitle = productData["productTitle"] as! String {
self.productTitle = productTitle
}
} else {
println(error)
}
}
}
productData: PFObject? object is an optional itself. You can't subscript over it yet, because it needs to be unwrapped before. You can replace the productData != nil check with optional chaining.
In Swift 1.2 you can do that and your error checking in the same statement:
if let productTitle = productData?["productTitle"] as? String
where error == nil {
self.productTitle = productTitle
}
Note the additional ? between the productData and the square brackets.
I am having trouble translating Parse documentation into new Swift requirements. I want to update an object but I keep getting back an error that I can't assign a value of type Bool to type AnyObject? I know the column for "viewed" is Bool. Here is my code.
var query = PFQuery(className:"Post")
query.getObjectInBackgroundWithId(self.threadImageIds[objectIDkey]) {
(object, error) -> Void in
if error != nil {
println(error)
} else {
object["viewed"] = true // this is where error is occuring
object!.saveInBackground()
}
}
Thanks in advance.
After a lot of searching and trying to unwrap optionals the way Swift wants me to, the following worked
query.getObjectInBackgroundWithId(self.threadImageIds[objectIDkey]) {
(object, error) -> Void in
if error != nil {
println(error)
} else {
if let object = object {
object["viewed"] = true as Bool
}
object!.saveInBackground()
}
}
You can't store a BOOL there, you need to use a NSNumber of a BOOL. Try true as NSNumber
It is not working because you're trying to apply the subscript to the optional and not to the object, so try unwrapping
object!["viewed"] = true
I have the following code:
//start the update
var query2 = PFQuery(className:"\(selectedShow)_schedule")
query2.getObjectInBackgroundWithId(idOfObject) {
(objectSend: PFObject!, error: NSError!) -> Void in
if error != nil {
NSLog("%#", error)
} else {
objectSend["student"] = "test"
objectSend.saveEventually()
println("ran")
}
}
And when I try to run it, it gives me the error:
fatal error: unexpectedly found nil while unwrapping an Optional value
and highlights this line:
objectSend["student"] = "test"
What could be going wrong?
The variable was not wrapped with an optional.
I want to display the highest scores of a GKPlayer with a GKLeaderboard in Swift.
func login() {
if (GKLocalPlayer.localPlayer().authenticated) {
var leaderboardRequest: GKLeaderboard!
leaderboardRequest.identifier = "Best_Score"
// Error: fatal error: unexpectedly found nil while unwrapping an Optional value
func loadLeaderboardsWithCompletionHandler(completionHandler: (([AnyObject]!,
NSError!) -> Void)!) {
var localPlayerScore: GKScore = leaderboardRequest.localPlayerScore
}
}
}
Though, func loadLeaderboardsWithCompletionHandler returns this error message: fatal error: unexpectedly found nil while unwrapping an Optional value because I'm forcing unwrapping an Optional that contains nil.
Where's the error with my code?
You're declaring GKLeaderboard, but not initializing it. Note also that loadLeaderboardWithCompletionHandler is a class function of GKLeaderBoard. Do this instead:
if (GKLocalPlayer.localPlayer().authenticated) {
GKLeaderboard.loadLeaderboardsWithCompletionHandler { objects, error in
if let e = error {
println(e)
} else {
if let leaderboards = objects as? [GKLeaderboard] {
for leaderboard in leaderboards {
if let localPlayerScore = leaderboard.localPlayerScore {
println(localPlayerScore)
}
}
}
}
}
}
As a sidenote, it's not safe to use implicitly unwrapped optionals, i.e., anything declared with a !. Take for example your program here: you can compile it and have to dig through your code to find where the runtime error actually occurred. If you would have declared var leaderBoardRequest: GKLeaderBoard?, you would have been able to identify the source of your problem immediately without having to compile and run.