Saving data from two containerviews - swift

First of all i wanne apologize for the code that will be used. I'am completely new to programming in general and it probably looks like .... :)
My problem is the following;
I have 1 ViewController (VC1) with 2 embedded container views (both TableViewControllers). Causs of the UI layout i want for my app i couldn't just use 1 TableVieController. Both of these container views have Textfields, labels, pickerviews that needs to be provided with data by the user.
Now i want to save all this data with 1 button from the VC1.
Everything displays without error but when i tap the save button is gives me the following error:
Could not cast value of type AddRaptorTableVCContainerOne' (0x1099ad840) to AddRaptorTableVCContainerTwo' (0x1099ad270).
Thanks in advance!
#IBAction func addRaptorSaveButton(sender: UIBarButtonItem) {
// Reference to childViewController
let childViewOne = childViewControllers.last as! AddRaptorTableVCContainerOne
let childViewTwo = childViewControllers.last as! AddRaptorTableVCContainerTwo
// Reference moc
let manObjCon = self.manObjCon
let addRaptorEntity = NSEntityDescription.entityForName("AddRaptorEntity", inManagedObjectContext: manObjCon!)
// Create instance of data model and initialize
var newRaptor = AddRaptorEntity(entity: addRaptorEntity!, insertIntoManagedObjectContext: manObjCon)
// Map our properties
newRaptor.image = UIImageJPEGRepresentation(self.addImageView.image, 1)
newRaptor.name = childViewOne.nameTextField.text
newRaptor.ringNo = childViewTwo.ringNoInputTextField.text
// Save our context
var error: NSError?
manObjCon!.save(nil)
println(newRaptor)

In two lines, you're saying that childViewControllers.last is two different things. Check whats actually in childViewControllers, using the debugger or by printing, and pick the right thing to cast as AddRaptorTableVCContainerTwo.

Related

Text label not updating on screen, even though it shows up on `print()`

I'm writing an application which has an NSSplitViewController as the main View-Controller. I have it linked-up so that clicking a button in the menubar will trigger an #IBAction which then calls a function in one of the sub-View-Controllers.
if let board = storyboard {
let imageController = board.instantiateController(withIdentifier: "VC_image_ID") as! VC_image
imageController.viewDidAppear() // necessary or else I'll get an "Unexpectedly found nil" later on
DispatchQueue.global().async{imageController.processImage(path)} // path variable was set earlier in the code, but not shown here
}
Inside the sub-View-Controller (named VC_image), I'm trying to change the stringValue of a label by using the following code:
public func processImage(_ path: String) {
DispatchQueue.main.async {
self.imageText.stringValue = path
print(self.imageText.stringValue)
}
}
Although the imageText.stringValue actually seems to have changed based on the fact that it prints the updated text (through the console), the text in the window never changes. Why is this happening? The reason is probably really obvious to professionals, but I'm still an amateur and can't figure it out. Thanks.

How do I put the complete UserDefaults list into a tableview - Swift 3

I am trying to put the list of UserDefaullts into a UITableView. I just want each key that I have saved to be able to show up in an individual cell. I placed all the individual items in variables so that they can be easily called. Here is one for example:
var A = UserDefaults.standard.string(forKey: "A")
I want to be able to put these in an array, but not every var is going to necessarily be used.
I'm sorry if this does not make much sense, I am not able to explain this very well. If you would like me to clarify anything please let me know!
Thanks
So let say you set your items into UserDefaults like this:
let array = ["one", "two", "three"]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "StringArray")
Then you retrieve the items as an array as the following:
let defaults = UserDefaults.standard
let array = defaults.stringArray(forKey: "StringArray") ?? [String]()
Then use the array as your UITableView datasource.
To get all values/keys from User Defaults:
Values:
print(UserDefaults.standard.dictionaryRepresentation().values)
Keys:
print(UserDefaults.standard.dictionaryRepresentation().keys)

Retrieving NSOrderedSet from Core Data and casting it to entity managedObjectSubclasss

Im making a Fitness app to learn Core data, and I have found that I need to let the user store every performed workout as a WorkoutLog item, and in there, there should be a series of ExerciseLogs which represents performances of that exercise (it contains each lift and also a reference to the actual exercise design).
Problem is that after a while i realize that i need to have these ordered, so that the next time i want to show the user their workout, the order that the exercisese were performed should be the same.
So I checked "ordered" in the top right of the image there, and now my code is in dire need of an update. I have tried to read as much as I could about working with NSOrderedSet and how to fetch them from core data and then manipulate them, but I havent really found much of use to me. (I have no experice in objective-c)
For example my code that used to be:
static func deleteWorkoutLog(_ workoutLogToDelete: WorkoutLog) {
guard let exerciseLogsToDelete = workoutLogToDelete.loggedExercises as? Set<ExerciseLog> else {
print("error unwrapping logged exercises in deleteWorkoutLog")
return
}
I get the error: .../DatabaseFacade.swift:84:77: Cast from 'NSOrderedSet?' to unrelated type 'Set' always fails
So what ive learned about sets and core data no longer seems applicable.
Im far from an expert in programming, but im very eager to learn how to get access to the loggedExercises instances.
TLDR; Is there a way to cast NSOrderedSet to something I can work with? How do we usually work with NSManagedSets from core data? Do we cast them to Arrays or MutableSets? I would very much appreciate an example or two on how to get started with retrieving and using these ordered sets!
Thanks
For anyone else wondering how to get started with orderedSets in core data:
After setting my the WorkoutLog.loggedExercises "to-many" relationship to be ordered, I managed to access them through the mutableOrderedSetValue function like this:
static func deleteWorkoutLog(_ workoutLogToDelete: WorkoutLog) {
let orderedExerciseLogs: NSMutableOrderedSet = workoutLogToDelete.mutableOrderedSetValue(forKey: "loggedExercises")
let exerciseLogsToDelete = orderedExerciseLogs.array
for exerciseLog in exerciseLogsToDelete {
guard let exerciseLog = exerciseLog as? ExerciseLog else {
return
}
Works great so far.
And to rearrange the NSOrderedSet I ended up doing something like this:
// Swap the order of the orderedSet
if let orderedExerciseLogs: NSOrderedSet = dataSourceWorkoutLog.loggedExercises {
var exerciseLogsAsArray = orderedExerciseLogs.array as! [ExerciseLog]
let temp = exerciseLogsAsArray[indexA]
exerciseLogsAsArray[indexA] = exerciseLogsAsArray[indexB]
exerciseLogsAsArray[indexB] = temp
let exerciseLogsAsOrderedeSet = NSOrderedSet(array: exerciseLogsAsArray)
dataSourceWorkoutLog.loggedExercises = exerciseLogsAsOrderedeSet
}

Error when I want to access a row via the indexPath in a tableViewController

I am making a chat app. I am having a problem while accessing an array of objects via indexPath(row) of a tableViewController. It is giving me an error: " Cannot subscript a value of type '[AnyObject]?'" The code is below. How do I fix this?
var user1 = PFUser.currentUser()
var user2 = self.objects[indexPath.row] as! PFUser
You may change the declaration of your self.objects to:
var objects = Array<PFUser>()
and use it like:
let user = self.objects[indexPath.row] as BusinessLocation!
Since you have specified the type, it won't consider it as AnyObject.

Making a counter app - Do I have to do something after saving to Core Data?

Trying my hand in Swift and creating my first "app". I'm essentially creating a cookie-clicker clone where you just click an image in the center of your screen repeatedly to increment your score.
I'm experiencing some issues where clicking the image once will increment my score by 1, but upon clicking it again, the score stays 1.
I'm almost positive I'm supposed to do something after saving to CoreData - I just don't know what. Do I have to refresh the View? Sorry for the newbie question
#IBAction func tapHomeImage(sender: AnyObject) {
//Score is the name of my Entity, with "points" being an attribute
let entity = NSEntityDescription.entityForName("Score", inManagedObjectContext: managedObjectContext!)
let score = Score(entity: entity!, insertIntoManagedObjectContext: managedObjectContext!)
// **As an aside question, is there a more efficient way to code the below? The issue I have is that score.points is of type NSNumber
let intScore = score.points as Int
let incrementedIntScore = intScore + 1
score.points = NSNumber(integer: incrementedIntScore)
var error: NSError?
managedObjectContext?.save(&error)
//homeScoreLabel is an IBOutlet for the Score displayed on the page
homeScoreLabel?.text = "\(score.points)"
}
Thank you very much!
You don't need to do anything after saving, you need to do something before calling this method. You need to find an instance of Score that already exists, and use that.
When you get to this line:
let score = Score(entity: entity!, insertIntoManagedObjectContext: managedObjectContext!)
You create a new instance of the Score entity, every time this method runs. So when you do this:
let intScore = score.points as Int
let incrementedIntScore = intScore + 1
score.points = NSNumber(integer: incrementedIntScore)
You're working with a brand new instance every time. The score is initially zero, and you always increase it to 1.
What you should do:
Use a single instance of Score and save that as a property of your view controller. That is, have something like this:
var score: Score?
Assign a value to this property once, when the view controller loads. Since you're saving data, you should use executeFetchRequest to look up a previously-saved instance. If no previous instance exists, then create a new one via insertIntoManagedObjectContext.
Use that instance in this IBAction.
There are other ways to fix the code. The key is to make sure that you use the same instance of Score every time instead of creating a new one at every tap.