Error after xcode 8 update - NSUserDefaults - ios

After updating to Xcode 8.0 and iOS 10, I am getting an error in my code that I didn't before. Let me just walk you through the code that is bugging me.
viewDidLoad:
struct defaultsKeys {
static var localStrings = ""
}
Outside button (IBAction):
var storeUserData = NSUserDefaults.standardUserDefaults()
Inside button (IBAction):
let earlierStrings = storeUserData.stringForKey("localStrings")
The last one, inside the button, is the line that is giving me an error. I am now getting this error:
fatal error: unexpectedly found nil while unwrapping an Optional value
And I wasn't before the update? Has something changed about NSUserDefaults? I am very confused and I hope you can help me :-)

First of all if you want to pass around values inside your program just use local variables as #vikingosegundo stated. Declare local variables and use them.
Second, use NSUserDefault when you want to store variables like for example user-settings or preferences. Do also follow #Adils advice. Use them as follows:
Set value:
NSUserDefaults.standardUserDefaults().setObject("YOUR STRING", forKey: "key")
Get value:
NSUserDefaults.standardUserDefaults().stringForKey("key")

Related

defaultCalendarForNewEvents is defined as optional however can't use optional binding to check if it's nil

I'm adding new functionality in my app, which is the ability to add an event in the default calendar set up on the phone. I get the permission and am ready to add the event. I check to see if there is an actual default calendar, but I get the error:
Initializer for conditional binding must have Optional type, not
'EKCalendar'
Now, defaultCalendarForNewEvents is an Optional (see definition below) and it should be perfectly fine to use optional binding to check if it's nil or not. What am I missing?
defaultCalendarForNewEvents definition in EKEventStore.h:
open var defaultCalendarForNewEvents: EKCalendar? { get }
I'm using Swift 3 on iOS11.2.(Edited to correct the Swift version I'm using.)
Here's the code:
if let defaultCalendar = eventStore.defaultCalendarForNewEvents { <-- error line
newEvent.title = "Some Event Name"
newEvent.startDate = Date()
newEvent.endDate = Date()
}
I asked this question at the Swift discussion forum at swift.org and got a response. So as per the response, 'defaultCalendarForNewEvents' was marked non-optional in Swift 3 by accident and that was fixed in Swift 4. That's why there was a discrepancy: documentation showing declaration in Swift 4 but optional binding failing as I'm on Swift 3. Hope this helps someone who is having the same issue.
I was also told that this issue was not release-noted as it was a minor update.
The error is telling you that the defaultCalendarForNewEvents is not, in fact, an Optional. Perhaps there is some nil-coalescing or something else happening that is not visible to you. Regardless, if the compiler is telling you it's not optional there's no need to fight for optional binding.

NSCoding and Bools Swift 3

For whatever reason my application crashes everytime it decodes my Bool value. It didn't crash before I updated to Swift 3. I have no idea what I'm doing wrong. If I take out the Bool value my application runs fine without crashing.
This has been changed for Swift 3. There are associated decode...() functions for various different types.
The correct syntax is now:
let myBool = aDecoder.decodeBool(forKey: PropertyKey.completedKey)

Swift 2.0 Subscript issues with Dictionary

I've looked at the other questions on here about subscripting with dictionaries and I didn't see anything that quite fit what my scenario is. It may be that I'm still too new to Swift to realize it but in any case here is my scenario. I'm getting the typical can't "Subscript" dictionary with type string. I've seen the posts on here about it being an optional and needing to unwrap it however when I try that, Xcode suggests that I remove the !, so I do that, then I get the subscript error.
I've watched tons of tutorials on swift development and a lot of them use playgrounds and I never remembered seeing anyone have to do this in any of the tutorials. So I tried the same thing in a playground and it worked.
Here is what I have in the ViewController that DOESN'T work.
var validFields:Dictionary = ["loanBalanceInput":false,"cashOutInput":false,"appraisedValueInput":false,"interestRateInput":false]
func validationSuccess(sender:UITextField){
sender.backgroundColor = green
switch sender {
case loanBalanceInput:
validFields["loanBalanceInput"] = true
break
default:
break
}
}
What I've done is create a dictionary of strings that refer to textfields and their validation status to track whether or not they have been validated. The concept is that when everything in the dictionary is true, I can activate the calculate button.
However I get the "cannot subscript a value of type dictionary with an index of type string" error... However this code in a playground works...
var validatedFields:Dictionary = ["loanBalanceInput":false,"cashOutInput":false,"appraisedValueInput":false,"interestRateInput":false]
validatedFields["loanBalanceInput"]
validatedFields["loanBalanceInput"] = true
I don't understand what's going on here. Is it because this is an optional?
#IBOutlet weak var loanBalanceInput: UITextField!
I'm not unwrapping it in my switch? I'm not trying to get at the value of loanBalanceInput though, I'm just checking to see if it was the sender.
Normally a Swift Dictionary declaration needs also the type of the containing keys and values like
var validFields: Dictionary<String,Bool> = [" ...
but as the compiler can infer the type just delete the annotation.

'PFObject' does not have a member named 'subscript'

I understand, this particular error was already posted here and there and the code is somewhat basic, but I myself still unable to figure this one out & I need advice.
The thing is when I add the first two lines of code provided on parse.com for saving objects
var gameScore = PFObject(className:"GameScore")
gameScore["score"] = 1337
I get the following error for the second line:
'PFObject' does not have a member named 'subscript'
I'm on Xcode 6.3 beta 2.
All required libraries are linked with binary, <Parse/Parse.h> imported via BridgeHeader.
What syntax should I use?
This is happening due to the 1.6.4 version of the parse sdk which added Objective-C Nullability Annotations to the framework. In particular the file Parse/PFObject.h defines:
- (PF_NULLABLE_S id)objectForKeyedSubscript:(NSString *)key;
which is causing the Swift compile error. Removing the PF_NULLABLE_S fixes the problem.
On the other hand it seems correct that an object for a keyed subscript might be nil, so I suspect this is a Swift bug...
The problem seems to be the changed method signature, as kashif suggested. Swift doesn't seem to be able to bridge to the Objective-C method because the signature no longer matches the subscript method names.
Workaround 1
You can work around this without modifying the framework by calling the subscript method directly, instead of using the [] operator:
Instead of using the instruction below for getting the value of a particular key:
let str = user["key-name"] as? Bool
Please use the following instruction:
let str = user.objectForKey("key-name") as? Bool
and
Instead of using the instruction below for setting the value of a particular key:
user["key-name"] = "Bla bla"
Please use the following instruction:
user.setObject("Bla bla", forKey: "key-name")
Workaround 2
Another solution is to add an extension on PFObject that implements the subscript member and calls setValue:forKey::
extension PFObject {
subscript(index: String) -> AnyObject? {
get {
return self.valueForKey(index)
}
set(newValue) {
if let newValue: AnyObject = newValue {
self.setValue(newValue, forKey: index)
}
}
}
}
Note that this second workaround isn't entirely safe, since I'm not sure how Parse actually implements the subscript methods (maybe they do more than just calling setValue:forKey - it has worked in my simple test cases, so it seems like a valid workaround until this is fixed in Parse/Swift.
I've successfully run your exact code.
First, make sure you are indeed saving the object in the background, after you set the new value:
gameScore.save()
I would double check for misspellings in the class name and subclass; if they are incorrect, it will not work.
If that's not the problem, verify in Parse that the "score" subclass is set to be a number. If you accidentally set it to be a string, setting it as an integer will not work.
If these suggestions have not hit the solution, then I'm not sure what the problem is. Hope I helped.
I encountered a similar error with Parse 1.6.4 and 1.6.5 in the PFConstants.h header file with method parameters.
Xcode 6.3 beta 4 has a note in the "New in..." section regarding nullability operators.
Moving the nullability operator between the pointer operator and the variable name seems to comply/compile.
Changing:
PF_NULLABLE_S NSError *error
to:
NSError * PF_NULLABLE_S error
(i.e., NSError* __nullable error)
... resolved the compiler error.
This also worked for block parameters defined with id. So...
PF_NULLABLE_S id object
becomes:
id PF_NULLABLE_S object
In the above case, perhaps:
- (id PF_NULLABLE_S)objectForKeyedSubscript:(NSString *)key;
I.e., the nullability operator is after the pointer type.
I know its been a while but I encountered a similar problem when I was starting my first Parse application with SDK version 1.9.1.
The Quickstart guide had the code below as an example as to how to save values:
let testObject = PFObject(className: "TestObject")
testObject["foo"] = "bar"
testObject.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
println("Object has been saved.")
}
But, the line testObject["foo"] = "bar" returned the error 'PFObject' does not have a member named 'subscript'. I was able to work around the problem by changing the line to testObject.setValue("bar", forKey: "foo"). (As suggested by a tutorial video on YouTube: https://www.youtube.com/watch?v=Q6kTw_cK3zY)

How to debug 'fatal error: unexpectedly found nil while unwrapping an Optional value'

There are a lot of questions on Stack Overflow related to this error. I’ve read some excellent posts on how Optionals work and this error in particular. However, I haven’t found any information about the best way to figure out which value is being set to nil and causing the error in the first place.
Are there any good debugging techniques to find out which Optional is causing this error?
Here's at least half an answer (would the other respondents please read the question first!): Use the simulator instead of an actual iOS device.
The debugger seems to be pretty good at pointing to the line with the maltreated optional that's causing the trouble... unless you are like me, choosing to run the code on an iOS device directly from time to time. In the latter case, the debugger lands me right in the middle of some assembler code with no sensible stack trace. Switching back to the simulator gives the exact line of code at fault.
You Xcode does not crash at the incorrect line of code?
This does not response to the question but it's important to note:
When you are not sure about an optional variable, you have to verify if it contains value or not, by using a pattern like this:
var myOptional : String?
if let aString = myOptional {
//do your work with aString.
}
What basically optional value is "?" when you place ? after a datatype that is optional while if it is unwrapped and a nil appears theres no error but it you place "!" exclamation mark after datatype then if it unwrap the variable and nil appears then there's crash or error so often use optional as
var myVariable : DataType ? = DataType()
or
var myVariable : DataType ? = nil
or
var myVariable : DataType ? = value
An optional in Swift is a variable that can hold either a value or no value. Optionals are written by appending a ? to the type:
var myOptionalString:String? = "Hello"
Some places optionals are useful:
When a property can be there or not there, like middleName or spouse
in a Person class
When a method can return a value or nothing, like
searching for a match in an array
When a method can return either a result or get an error and
return nothing
Delegate properties (which don't always have to be set)
For weak properties in classes. The thing they point to can
be set to nil
For a large resource that might have to be released to
reclaim memory
https://medium.com/#rrridges/swift-optionals-a10dcfd8aab5

Resources