is the init method not working properly in swift - swift

With the code below, the local songs variable is never able to be iterated despite all the checks to the contrary ( println shows the value stored ). The other thing is that the Xcode debugger seems to jump all over the place in the init method.
let gLibraryManager = LibraryManager()
class LibraryManager {
var Songs = Dictionary<String, String>()
init() {
println("struct being initialized from NSDefaults")
let userDefaults = NSUserDefaults.standardUserDefaults();
var result:AnyObject = userDefaults.objectForKey(LIKED_LIST)
println(result)
var local = result as? Dictionary<String,String>
if local != nil {
println("local not nil: \(local!)")
for (id,title) in local! {
Songs[id] = title
}
if Songs.count > 0 {
println("NSDefaults detected: \(Songs)")
} else {
println("no NSDefaults detected. Initializing empty")
}
}
}

ok. i figured out what is was.
I had set the Swift Compiler - Code Generation. Optimization level to -Fastest. This was to prevent the extremely slow creation of Dictionaries.
However, it appears this breaks the ability to iterate structures.
It also seems to resolve the weird bouncing around of breakpoints.
This was a needle in a haystack that tooks many hours. I guess the moral of the story is not to mess with compiler flags yet.

Related

How to fetch core data objects into Dictionary in Swift?

I've saved objects in core data, and I am looking how to fetch those objects as a Dictionary
Here is an example of my code where sections is keys for the dictionary and Company as an array of core data objects.
private var companies = Dictionary<String, Array<Company>>()
private var sections: [String] = ["Pending", "Active", "Pending"]
override func viewWillAppear(_ animated: Bool) {
let fetchRequest : NSFetchRequest<Company> = Company.fetchRequest()
let moc = DatabaseController.getContext()
do {
let request = try moc.fetch(fetchRequest)
for case let (index, object) in request.enumerated() {
companies[sections[index]]!.append(object)
}
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}}
When I am trying to execute my code, I have an error:
fatal error: unexpectedly found nil while unwrapping an Optional value
Could anyone help me with that issue?
That error message means that you're force unwrapping an optional that doesn't have a value. In other words you're using ! where you shouldn't. (You should basically never use the force unwrap operator (!).)
Let's look at the line where you do that:
companies[sections[index]]!.append(object)
If we break this down and add the inferred types we have:
let section: String? = sections[index]
let companyArray: Array<Company> = companies[section]!
You're crashing because companies starts off empty, so asking for any of the arrays will return nil. (Actually, I'm not sure how your code is compiling, since you can't subscript into the dictionary with an optional.)
However, if you fix that, we still have a problem because you're using the index of the fetched array to look up the section. If you have more than three companies, that will start to fail.
I suspect you want something like:
for let company in result {
if var companyArray = companies[company.status] {
companyArray.append(company)
} else {
companies[company.status] = [company]
}
}
Where status is an invented property on Company that returns a String like "Pending" or "Active".
I've found the solution, just need to use NSFetchResultController in order to display data in TableView by different sections.

Command failed due to signal: Segmentation fault: 11 | Xcode 7.2

I was asked to migrate a rather large app to Swift 2. The compiler keeps throwing segmentation fault: 11 errors for one function, present in different modules of the app's logic (only difference being variables used):
func loadMoreContent() {
if let collection = self.ratingsCollection where collection.identifier != 0,
let totalEntries = collection.totalEntries,
let objects = self.ratings?.count where objects < totalEntries {
self.ratingsCollection = nil
collection.nextPage().onSuccess { (value) in
if let collection = value as? Collection<Rating> {
self.ratingsCollection = collection
} else {
self.ratingsCollection = Collection<Rating>(identifier: 0)
}
}.onFailure { error in
self.ratingsCollection = Collection<Rating>(identifier: 0)
}
}
}
Here are the errors themselves:
1. While type-checking 'loadMoreContent' at (path redacted).swift:46:3
2. While type-checking expression at [(path redacted).swift:54:9 - line:64:9]
RangeText="collection.nextPage().onSuccess { (value) in
if let collection = value as? Collection<Rating> {
self.ratingsCollection = collection
} else {
self.ratingsCollection = Collection<Rating>(identifier: 0)
}
}.onFailure { error in
self.ratingsCollection = Collection<Rating>(identifier: 0)
}"
3. While loading members for declaration 0x7fdda42ea2b0 at <invalid loc>
4. While deserializing 'producer' (FuncDecl #340)
Does anyone have any idea what can be wrong with this function at first glance? I should add it compiles with no changes in Xcode 6 / Swift 1.2.
This is a hair pulling error especially common in XCode7.
Occasionally the usual XCode stupid bug protocol (clean, XCode Restart, clean, build) fixes it. However, often it is due to one or more offending lines of code. This doesn't necessarily mean there is a bug in the code, either!
So, before restarting, it is sometimes useful to undo recent changes sequentially and trying to build as you go along. If any of your dependencies or frameworks have been updated since your last successful build, these could be a likely candidate.
There are a couple things that seem to produce this error fairly regularly. So please add to this list concisely if you can isolate specific issues that CONSISTENTLY cause errors for you:
1) String concatenation using the plus operator in calls to methods that use autoclosures (found in calls to XCGLogger):
public func myFunc(#autoclosure closure: () -> String?){
// do something
}
someInstance.myFunc("Hi " + nameStr + "!")
2) failure to call super.init() from subclass especially when super class is using a default initializer (you haven't explicitly created your own init)
3) Accidentally using a single equals sign to test for equality (using = instead of == ) especially in complex statement such as in this answer.

"Ambiguous reference to member map" when attempting to append/replace array element

Several SO posts like this deal with the same error message, but none of those solutions work. It appears like this could be a case of a misleading error message.
The code below generates an "Ambiguous reference to member map" error for the map call.
Anyone know why?
func saveUser(user: User) {
var userDicts = masterDict["users"] as! [[String:AnyObject]]
let newDict = user.getDict()
// Replace matching element with <newDict>
let replaced = false
masterDict["users"] = userDicts.map {
if ($0["id"] as String! == user.getId()) {
replaced = true
return newDict
} else {
return $0 as [String:AnyObject]
}
}
// If no match found, means must add new user
if (!replaced) {
userDicts.append(newDict)
}
}
Unfortunately, swift is not perfect and can not infer types at all times, this is why you are getting the ambiguous reference. Try userDicts.map {val -> [String:AnyObject] in and swap out $0 for val This will explicitly tell the map that the values coming in are [String:AnyObject], and should be able to return said type
Never isolated the cause of the error so switched to using a for loop, creating a new array inside the loop, and calling masterDict["users"] = newArray after the loop. Not the cleanest, but it fixes the error.

Swift EXC_BAD_ACCESS with a corrupted object?

For some strange reason, I'm encountering an EXC_BAD_ACCESS, specifically in unwrapping and referencing a field. (Reproducible on the Xcode 7 GM.)
Here's the relevant code:
// FIXME: BUGGY
let conv_id = client_conversation.conversation_id //!.id
print("ABOUT TO DIE: \(conv_id?.id)")
if conv_id!.id as? String != nil {
conv_id!.id = "hi"
}
It crashes at the print() statement. Not sure what I can adequately do to fix this. I've tried the malloc() debugging, Zombie objects, and hand-debugging via backtrace.
I've added the definition of these objects:
class Message : NSObject {
required override init() {
super.init()
}
}
class CONVERSATION_ID : Message {
var id: NSString = ""
}
class CLIENT_CONVERSATION : Message {
var conversation_id: CONVERSATION_ID?
var type = ConversationType()
var name: NSString?
var self_conversation_state = CLIENT_CONVERSATION_INTERNAL_STATE()
var read_state = [CLIENT_CONVERSATION_READ_STATE]()
var current_participant = [USER_ID]()
var participant_data = [CLIENT_CONVERSATION_PARTICIPANT_DATA]()
}
Another example issue: while print(conv_id!) prints
(
"sample string"
)
I can't seem to be able to access the string directly.
Any time you say ! you are inviting a crash. Rewrite your code so that ! never appears. Know your Optionals and unwrap every single one of them safely. Learn about how to compare an Optional with nil before unwrapping, or how to use the if let construct.
Also, note that this line is sheer nonsense (what I call a "false cast"):
if conv_id!.id as? String != nil {
An NSString is always a String; I am surprised that the compiler is not warning you about this. Thus, the test is meaningless.
Your code should therefore read like this:
let conv_id = client_conversation.conversation_id
conv_id?.id = "hi"
Notice that there are no false casts and exclamation marks.

Swift If program

Still a beginner with just playing around with some basic functions in swift.
Can someone tell me what is wrong with this code?
import UIKit
var guessInt: Int
var randomNum = arc4random_uniform(10)
if Int(randomNum) == guessInt {
println ("correct")
} else {
println; "no, the number is not. guess again"
}
So far the only error I'm getting is that
guessInt
is being used before being initialized!
I've tried to type everything again but still have the same error.
Thanks in advance.
In Swift you cannot read a value before it's set, which you're doing here:
if Int(randomNum) == guessInt
If you change your declaration from this:
var guessInt:Int
to this:
var guessInt = 6
then your code will work as expected (assuming you want the user's guess to be 6).
You've declared guessInt but now you need to initialize, or set it to some initial value.
For example:
let guessInt = 3
Another option is to declare guessInt as an "Optional", meaning that it can be nil, in fact it will be initialized to nil. This will print "no, ...." until you assign guessInit to a non nil value in the range of values produced by arc4random_uniform(10), but it will compile and run cleanly.
var guessInt:Int? // note the ? after Int this marks it as an Optional
var randomNum = arc4random_uniform(10)
if Int(randomNum) == guessInt {
println ("correct")
} else {
println; "no, the number is not. guess again"
}