Button in View Should Reset Array in ModelController But Doesn't - ios

I am attempting have one of my views present the user with the option to reset an array that they have edited to it's original form. I am currently attempting to do this using NSNotificationCenter.
The current process:
User flips through a series of cards, each of which are pulled from the array experiments (which has been shuffled beforehand but I don't think that's relevant to this issue) and deletes ones they don't want to see again when the array loops back around.
User decides they want to start again with a fresh array.
User clicks "Home" which brings them to AdditionalMenuViewController.swift which is set up with NSNotification center with an #IBAction that triggers the notification that the ModelController will listen to. Here's AdditionalMenuViewController.swift.
let mySpecialNotificationKey = "com.example.specialNotificationKey"
class AdditionalMenuViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "resetArray", name: mySpecialNotificationKey, object: nil)
}
#IBAction func notify(){
NSNotificationCenter.defaultCenter().postNotificationName(mySpecialNotificationKey, object: self)
}
func resetArray() {
println("done")
}
}
That should trigger the listener in ModelController to reset the array and then allows the user to continue using the app but with the array reset. Here are the (I think!) relevant parts of ModelController.swift:
class ModelController: NSObject, UIPageViewControllerDataSource {
var experiments = NSMutableArray()
var menuIndex = 0
func shuffleArray(inout array: NSMutableArray) -> NSMutableArray
{
for var index = array.count - 1; index > 0; index--
{
// Random int from 0 to index-1
var j = Int(arc4random_uniform(UInt32(index-1)))
// Swap two array elements
// Notice '&' required as swap uses 'inout' parameters
swap(&array[index], &array[j])
}
return array
}
override init() {
super.init()
// Create the data model.
if let path = NSBundle.mainBundle().pathForResource("experiments", ofType: "plist") {
if let dict = NSDictionary(contentsOfFile: path) {
experiments.addObjectsFromArray(dict.objectForKey("experiments") as NSArray)
}
}
println(experiments)
shuffleArray(&experiments)
println(experiments)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "resetArray", name: mySpecialNotificationKey, object: nil)
}
func resetArray() {
if let path = NSBundle.mainBundle().pathForResource("experiments", ofType: "plist") {
if let dict = NSDictionary(contentsOfFile: path) {
experiments.addObjectsFromArray(dict.objectForKey("experiments") as NSArray)
}
}
shuffleArray(&experiments)
}
Currently it does create a new array but it is double the size of the original which tells me its running both the original and the reset functions. It also breaks all the pageViewController functionality that you can find in the default Page-Based Application in Xcode.
What am I missing here?
How can I both reset the array and then drop the user back into the flow of the Page-Based App?

rdelmar's suggestion worked perfectly. I now clear the array and then fill it with a freshly shuffled one.

Related

How can I create an Instance of NSManagedObject in a NotesApp without a Button - Apple's NoteApp Style?

I started learning programming and I decided to try out my first Note Taking App.
My Goal is to create an App similar to the iPhone's NoteApp. Therefore, I wanted the note's title be set when the User writes in the TextView as the first line. Therefore, I created a NoteViewController, which contains a TextView and a NoteIndexViewController, which is a TableViewController, both embedded in a NavigationController.
I'm also using Core Data to store the data.
The problem is that I don't know how I can commit those changes to the DataBase without using a button. I know how to create an instance of the NSManagedObject - in NoteIndexViewController to create new notes in the TableView using a Button:
#IBAction func addNotePressed(_ sender: UIBarButtonItem) {
let newNoteIndex = NoteIndex(context: self.context)
newNoteIndex.name = "Temporal Name"
notesArray.append(newNoteIndex)
saveNoteIndex()
performSegue(withIdentifier: K.segueToNote, sender: self)
}
But I'm completely lost if I want to commit the changes without a "Save Button" to create the instance and also committing changes. This is the code I got so far. Notice that I did not set any Note() object.
class NoteViewController: UIViewController {
var noteArray = [Note]()
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var selectedNote: NoteIndex? {
didSet {
loadData()
}
}
var firstLine: String?
#IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
if !textView.text.isEmpty {
if let newLine = textView.text.firstIndex(of: "\n") {
let firstLetter = textView.text.startIndex
let lineBrake = textView.text.index(before: newLine)
let lettersTillPosition = textView.text.distance(from: firstLetter, to: lineBrake)
firstLine = (textView.text as NSString).substring(to: lettersTillPosition)
} else {
if textView.text.count >= 30{
firstLine = (textView.text as NSString).substring(to: 30)
} else {
firstLine = (textView.text as NSString).substring(to: textView.text.count)
}
}
selectedNote!.name = firstLine
saveCurrentNote()
}
}
//MARK: - Data Manipulation Methods
func saveCurrentNote() {
do {
try context.save()
} catch {
print("Error saving cateogry \(error)")
}
}
func loadData(with request: NSFetchRequest<Note> = Note.fetchRequest()) {
// goToIndex is the relationship between the IndexNote entity and Note. And when Back button is pressed the code tend also to break in this part.
request.predicate = NSPredicate(format: "goToIndex.name MATCHES %#", selectedNote!.name!)
do {
noteArray = try context.fetch(request)
} catch {
print("This is a load error: \(error)")
}
}
}
extension NoteViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
saveCurrentNote()
}
}
Here is a possible solution for your question. You can use Notification Center to monitor if the user is interrupted and if so you can do a quick save.
Place these in the scene delegate
func sceneWillResignActive(_ scene: UIScene) {
let notificationName = NSNotification.Name(ReuseIdentifier.pause)
NotificationCenter.default.post(name: notificationName , object: nil)
}
func sceneDidDisconnect(_ scene: UIScene) {
let notificationName = NSNotification.Name(ReuseIdentifier.quit)
NotificationCenter.default.post(name: notificationName, object: nil)
}
Place something like this where the user data is being saved.
/// Monitors application state for major changes.
/// - Pause Observer: Adds observer that notifies application if application is no longer active (enters foreground).
/// - Quit Observer: Adds observer that notifies application if terminated.
private func checkForPauseOrQuit(){
NotificationCenter.default.addObserver(self,
selector: #selector(autoSave),
name: NSNotification.Name(ReuseIdentifier.pause),
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(autoSave),
name: NSNotification.Name(ReuseIdentifier.quit),
object: nil)
}
And then for your selector method you create your NSManagedObject and capture whatever values the user may have started typing.
On startup you do the reverse, and make sure to erase the values. This should function only as a temporary holding container not your main entity. Check out my note application for reference:
https://github.com/victis23/AwesomeNote/tree/WorkingBranch/AwesomeNote

How to terminate (not segue) just one view in Swift

I am wondering how to make just 1 view terminate in iOS. I am making an app such that in the viewDidLoad() it generates 52 random strings and appends them to an array. I have it so that when you shake the device, it will perform a segue.
The problem with this is that it keeps the items in the array that I mentioned earlier. This means that when it does the user goes into that view again, it will still have the 52 random strings, plus when it goes through the viewDidLoad function, it will append 52 more strings, so if the user doesn't terminate the whole entire app, but just segues out of the view and goes back in, there will be 104 strings and not 52.
I don't want the above to happen in my app, so I am wondering how you could just terminate this one view while also performing a segue so that this problem won't happen.
Here is some code from my app:
These are the arrays I had:
var theCardsTopPlayerHas = [""]
var theCardsBottomPlayerHas = [""]
var theCardsThatWork = ["2_of_clubs", "2_of_diamonds", "2_of_hearts", "2_of_spades", "3_of_clubs", "3_of_diamonds", "3_of_hearts", "3_of_spades", "4_of_clubs", "4_of_diamonds", "4_of_hearts", "4_of_spades", "5_of_clubs", "5_of_diamonds", "5_of_hearts", "5_of_spades", "6_of_clubs", "6_of_diamonds", "6_of_hearts", "6_of_spades", "7_of_clubs", "7_of_diamonds", "7_of_hearts", "7_of_spades", "8_of_clubs", "8_of_diamonds", "8_of_hearts", "8_of_spades", "9_of_clubs", "9_of_diamonds", "9_of_hearts", "9_of_spades", "10_of_clubs", "10_of_diamonds", "10_of_hearts", "10_of_spades", "jack_of_clubs2", "jack_of_diamonds2", "jack_of_hearts2", "jack_of_spades2", "queen_of_clubs2", "queen_of_diamonds2", "queen_of_hearts2", "queen_of_spades2", "king_of_clubs2", "king_of_diamonds2", "king_of_hearts2", "king_of_spades2","ace_of_clubs", "ace_of_diamonds", "ace_of_hearts", "ace_of_spades"]
Here is what the viewDidLoad method has:
struct shuffledVar {
static var shuffled = [String]();
}
override func viewDidLoad() {
super.viewDidLoad()
upperLabelNumber.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
//MARK: - Shuffling Cards
for _ in 1...52 {
let shuffledCardList = Int(arc4random_uniform(UInt32(theCardsThatWork.count)))
let the_card = theCardsThatWork[shuffledCardList]
print("\(the_card)")
shuffledVar.shuffled.append(the_card)
theCardsThatWork.remove(at: shuffledCardList)
print("Finished Card")
}
theCardsTopPlayerHas = Array(shuffledVar.shuffled[0...25])
theCardsBottomPlayerHas = Array(shuffledVar.shuffled[26...51])
print("")
print(shuffledVar.shuffled)
print("")
print(theCardsTopPlayerHas)
print("")
print(theCardsBottomPlayerHas)
}
This is the code that segues the view:
override func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?) {
performSegue(withIdentifier: "friendToDashboard", sender: self)
}
Thank you!
The problem is that you are using a static var to store your array of strings.
To solve this problem there are several solutions depending on what you need. Here there are a couple of solutions:
Solution 1
If you really need to keep the shuffled array as a Singleto, then you can empty the shuffled array in the viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
shuffledVar.shuffled = []
upperLabelNumber.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
...
}
Solution 2
If you do not need to keep the shuffled array as a Singleton, then you can modify it as follows:
struct shuffledVar {
var shuffled = [String]();
}
var shuffled = shuffledVar()
override func viewDidLoad() {
super.viewDidLoad()
upperLabelNumber.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
//MARK: - Shuffling Cards
for _ in 1...52 {
let shuffledCardList = Int(arc4random_uniform(UInt32(theCardsThatWork.count)))
let the_card = theCardsThatWork[shuffledCardList]
print("\(the_card)")
shuffled.shuffled.append(the_card)
theCardsThatWork.remove(at: shuffledCardList)
print("Finished Card")
}
theCardsTopPlayerHas = Array(shuffled.shuffled[0...25])
theCardsBottomPlayerHas = Array(shuffled.shuffled[26...51])
print("")
print(shuffled.shuffled)
print("")
print(theCardsTopPlayerHas)
print("")
print(theCardsBottomPlayerHas)
}
You are using static var shuffled so you are using static variable. Do you really need a static variable? If not instead of:
struct shuffledVar {
static var shuffled = [String]();
}
use:
var shuffled:[String] = []
and then in code use:
shuffled.append(the_card)
But if you need this variable to be static (for example you are using it in some other view controller) just remove all elements before adding a new one:
//MARK: - Shuffling Cards
shuffledVar.shuffled.removeAll()
You can read more about static vars https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html and more about arrays: https://developer.apple.com/documentation/swift/array

passing data between view controllers without changing views

I want to pass data between two view controllers, but don't want the view to change when the users presses my save data button.
The users needs to fill in multiple data fields, and when finish can press another button to go to the second view controller.
I found many tutorials how to pass data using segue, but they all change view as soon as the 'save button is pressed'.
Any one can explain to me how to alter the code?
#Phillip Mills: here is how I used your code. (what am I doing wrong?)
code:
//////// declaring classes on FirstViewController (trying it first on only one ViewController)
class FakeVC1 {
func userInput() {
DataModel.shared.username = outbj14u.text
}
class FakeVC2 {
func viewAppears() {
if let name = DataModel.shared.username {
outbj14p.text = name
print("I have nothing to say")
}
}
}
class DataModel {
static let shared = DataModel()
var username: String?
}
////till here
//// here is where i call the functions
override func viewDidAppear(_ animated: Bool) {
FakeVC1().userInput()
FakeVC2().viewAppears()
if let xbj14p = UserDefaults.standard.object(forKey: "outbj14p") as? String
{
outbj14p.text = xbj14p
}
if let xbj14u = UserDefaults.standard.object(forKey: "outbj14u") as? String
{
outbj14u.text = xbj14u
}
////
#Phillip Mills: Below is what I have know. I think I got the code on the FirstViewController right, but the code on the Second View controller must be wrong. I don't get any errors, but the text field on the SecondViewController remains unchanged after putting input on in the FirstViewController
//// Code on the FirstViewController
class DataModel {
static let shared = DataModel()
var username: String?
}
#IBAction func savebj14p(_ sender: Any) {
outbj14p.text = inbj14p.text
DataModel.shared.username = outbj14p.text
UserDefaults.standard.set(inbj14p.text, forKey: "namebj14p")
}
//and on the SecondViewController
#IBOutlet weak var bj14u: UILabel! // connected to a label
//and
class DataModel {
static let shared = DataModel()
var username: String?
}
override func viewDidAppear(_ animated: Bool) {
if let name = DataModel.shared.username {
bj14u.text = name
}
}
In your case, don't pass data.
Create a shared object to act as your data model. When users fill in the fields, update the data model.
When the user moves to the second controller/view, that controller uses the data model object to show what it needs to.
class FakeVC1 {
func userInput() {
DataModel.shared.username = "Me"
}
}
class FakeVC2 {
func viewAppears() {
if let name = DataModel.shared.username {
print(name)
} else {
print("I have nothing to say")
}
}
}
class DataModel {
static let shared = DataModel()
var username: String?
}
FakeVC1().userInput()
FakeVC2().viewAppears()
If you need to pass value to another viewcontroller without changing the view , you can user NSNotificationCenter class
Refer this link for more details
NSNotificationCenter addObserver in Swift
what i will recommend is to use a global variable or array, you will have the info in all view controllers and you will be able to call it in your new view controller.

Swift iOS -How To Reload TableView Outside Of Firebase Observer .childAdded to Filter Out Duplicate Values?

I have a tabBar controller with 2 tabs: tabA which contains ClassA and tabB which contains ClassB. I send data to Firebase Database in tabA/ClassA and I observe the Database in tabB/ClassB where I retrieve it and add it to a tableView. Inside the tableView's cell I show the number of sneakers that are currently inside the database.
I know the difference between .observeSingleEvent( .value) vs .observe( .childAdded). I need live updates because while the data is getting sent in tabA, if I switch to tabB, I want to to see the new data get added to the tableView once tabA/ClassA is finished.
In ClassB I have my observer in viewWillAppear. I put it inside a pullDataFromFirebase() function and every time the view appears the function runs. I also have Notification observer that listens for the data to be sent in tabA/ClassA so that it will update the tableView. The notification event runs pullDataFromFirebase() again
In ClassA, inside the callback of the call to Firebase I have the Notification post to run the pullDataFromFirebase() function in ClassB.
The issue I'm running into is if I'm in tabB while the new data is updating, when it completes, the cell that displays the data has a count and the count is thrown off. I debugged it and the the sneakerModels array that holds the data is sometimes duplicating and triplicating the newly added data.
For example if I am in Class B and there are 2 pairs of sneakers in the database, the pullDataFromFirebase() func will run, and the tableView cell will show "You have 2 pairs of sneakers"
What was happening was if I switched to tabA/ClassA, then added 1 pair of sneakers, while it's updating I switched to tabB/ClassB, the cell would still say "You have 2 pairs of sneakers" but then once it updated the cell would say "You have 5 pairs of sneakers" and 5 cells would appear? If I switched tabs and came back it would correctly show "You have 3 pairs of sneakers" and the correct amount of cells.
That's where the Notification came in. Once I added that if I went through the same process and started with 2 sneakers the cell would say "You have 2 pairs of sneakers", I go to tabA, add another pair, switch back to tabB and still see "You have 2 pairs of sneakers". Once the data was sent the cell would briefly show "You have 5 pairs of sneakers" and show 5 cells, then it would correctly update to "You have 3 pairs of sneakers" and the correct amount of cells (I didn't have to switch tabs).
The Notification seemed to work but there was that brief incorrect moment.
I did some research and the most I could find were some posts that said I need to use a semaphore but apparently from several ppl who left comments below they said semaphores aren't meant to be used asynchronously. I had to update my question to exclude the semaphore reference.
Right now I'm running tableView.reloadData() in the completion handler of pullDataFromFirebase().
How do I reload the tableView outside of the observer once it's finished to prevent the duplicate values?
Model:
class SneakerModel{
var sneakerName:String?
}
tabB/ClassB:
ClassB: UIViewController, UITableViewDataSource, UITableViewDelegate{
var sneakerModels[SneakerModel]
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(pullDataFromFirebase), name: NSNotification.Name(rawValue: "pullFirebaseData"), object: nil)
}
override func viewWillAppear(_ animated: Bool){
super.viewWillAppear(animated)
pullDataFromFirebase()
}
func pullDataFromFirebase(){
sneakerRef?.observe( .childAdded, with: {
(snapshot) in
if let dict = snapshot.value as? [String:Any]{
let sneakerName = dict["sneakerName"] as? String
let sneakerModel = SneakerModel()
sneakerModel.sneakerName = sneakerName
self.sneakerModels.append(sneakerModel)
//firebase runs on main queue
self.tableView.reloadData()
}
})
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sneakerModels.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SneakerCell", for: indexPath) as! SneakerCell
let name = sneakerModels[indePath.row]
//I do something else with the sneakerName and how pairs of each I have
cell.sneakerCount = "You have \(sneakerModels.count) pairs of sneakers"
return cell
}
}
}
tabA/ClassA:
ClassA : UIViewController{
#IBAction fileprivate func postTapped(_ sender: UIButton) {
dict = [String:Any]()
dict.updateValue("Adidas", forKey: "sneakerName")
sneakerRef.?.updateChildValues(dict, withCompletionBlock: {
(error, ref) in
//1. show alert everything was successful
//2. post notification to ClassB to update tableView
NotificationCenter.default.post(name: Notification.Name(rawValue: "pullFirebaseData"), object: nil)
}
}
}
In other parts of my app I use a filterDuplicates method that I added as an extension to an Array to filter out duplicate elements. I got it from filter array duplicates:
extension Array {
func filterDuplicates(_ includeElement: #escaping (_ lhs:Element, _ rhs:Element) -> Bool) -> [Element]{
var results = [Element]()
forEach { (element) in
let existingElements = results.filter {
return includeElement(element, $0)
}
if existingElements.count == 0 {
results.append(element)
}
}
return results
}
}
I couldn't find anything particular on SO to my situation so I used the filterDuplicates method which was very convenient.
In my original code I have a date property that I should've added to the question. Any way I'm adding it here and that date property is what I need to use inside the filterDuplicates method to solve my problem:
Model:
class SneakerModel{
var sneakerName:String?
var dateInSecs: NSNumber?
}
Inside tabA/ClassA there is no need to use the Notification inside the Firebase callback however add the dateInSecs to the dict.
tabA/ClassA:
ClassA : UIViewController{
#IBAction fileprivate func postTapped(_ sender: UIButton) {
//you must add this or whichever date formatter your using
let dateInSecs:NSNumber? = Date().timeIntervalSince1970 as NSNumber?
dict = [String:Any]()
dict.updateValue("Adidas", forKey: "sneakerName")
dict.updateValue(dateInSecs!, forKey: "dateInSecs")//you must add this
sneakerRef.?.updateChildValues(dict, withCompletionBlock: {
(error, ref) in
// 1. show alert everything was successful
// 2. no need to use the Notification so I removed it
}
}
}
And in tabB/ClassB inside the completion handler of the Firebase observer in the pullDataFromFirebase() function I used the filterDuplicates method to filter out the duplicate elements that were showing up.
tabB/ClassB:
func pullDataFromFirebase(){
sneakerRef?.observe( .childAdded, with: {
(snapshot) in
if let dict = snapshot.value as? [String:Any]{
let sneakerName = dict["sneakerName"] as? String
let sneakerModel = SneakerModel()
sneakerModel.sneakerName = sneakerName
self.sneakerModels.append(sneakerModel)
// use the filterDuplicates method here
self.sneakerModels = self.sneakerModels.filterDuplicates{$0.dateInSecs == $1.dateInSecs}
self.tableView.reloadData()
}
})
}
Basically the filterDuplicates method loops through the sneakerModels array comparing each element to the dateInSecs and when it finds them it excludes the copies. I then reinitialize the sneakerModels with the results and everything is well.
Also take note that there isn't any need for the Notification observer inside ClassB's viewDidLoad so I removed it.

How to keep from having repeated items on a tableView due to a function triggered several times?

My issue is that I am querying elements in viewDidLoad and adding to the tableView. On another view, the user can add elements to Parse, that I am querying again on viewDidAppear to display only the newly added elements without requiring the view to re-load.
These elements are class of user with name, age etc...
On the viewDidAppear, I am querying the elements from Parse, going through a messy filtering to find out the ones that are not already displayed on the tableView, and then I trigger my function to add it.
It appears that even though I have removed duplicate items from my array, the function to set up my user (adding his name etc) gets called several times and consequently I still end up with duplicated items on my tableView.
The corresponding codes as below:
override func viewWillAppear(animated: Bool) {
var query = PFUser.query()
query!.whereKey("username", equalTo: PFUser.currentUser()!.username!)
query!.findObjectsInBackgroundWithBlock { (objects, NSError) -> Void in
if let objects = objects as? [PFObject] {
for member in objects {
if member["Network"] != nil {
var acceptedMembers: [String] = member["Network"] as! [String]
self.usernames = acceptedMembers
////
var query2 = PFUser.query()
query2?.findObjectsInBackgroundWithBlock({ (objects2, error2) -> Void in
if let objects2 = objects2 as? [PFUser] {
for otherUser in objects2 {
if contains(self.usernames, otherUser.username!) {
var arrayName1 = [String]()
arrayName1.append(otherUser.username!)
var arrayName2 = [String]()
for n in self.arrayMem {
arrayName2.append(n.name)
dispatch_async(dispatch_get_main_queue(), {
for extra in arrayName1 {
if contains(arrayName2, extra) {
} else {
var arrayName3 = [String]()
arrayName3.append(extra)
let unique3 = NSSet(array: arrayName3).allObjects
self.plusOne = unique3.first as! String
self.nameMember = self.plusOne as String
self.setName()
self.tableView.reloadData()
}
}
})
}
}}}}) }}}}
}
PS: I have tried cleaner solution to remove duplicate, converting my class to Hashable, then Equatable and using a simple function, however it turns up that this solution, messier as it is works more efficiently.
Anyway, the question here touches the function "self.setName()" that gets called repeatedly.
Do you have any idea how could this be fixed ?
Thank you infinitely,
A different approach would be to add a new object to your array after it's added in the other view controller and then add a new row for it into your table view. I would suggest communicating the newly formed object via an NSNotification.
View Controller with Table
Fetch your objects from Parse here, do it once in viewDidLoad
func fetchParseObjects () {}
Add an observer for this class to the NSNotificationCenter, also in viewDidLoad
NSNotificationCenter.defaultCenter().addObserver(self, selector: "objectUpdated:", name: "objectUpdated", object: nil)
Remove the observer in a deinit method
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self, name: "objectUpdated", object: nil)
}
func objectUpdated(notification: NSNotification) {
if let yourKindOfObject = notification.object as? YOUR_TYPE_HERE {
// Add, update or remove an item from the array that holds the original fetched data here based on the object
// Update your tableView accordingly (add, remove or update)
}
Where I have done something similarly I have created a custom object to hold some properties of what object needs to be updated and how it should be updated.
View Controller that Updates
Do what you normally do, but send a notification with a descriptive object to use to update your original data accordingly
NSNotificationCenter.defaultCenter().postNotificationName("objectUpdated", object: YOUR_OBJECT_WITH_UPDATE_DATA)

Resources