How to update a list item status automatically using NSNotificationCenter? - ios

For instance, in App Store when there's 2 different tabs of apps and some application appears in both tabs, when I click to download it in one, the app status in the other one is automatically updated. Is there a way to do so using NSNotificationCenter in iOS? Images below
So after I select the Gmail app for instance...
And then when I go back to the list of apps, its no longer asking me to obtain the app, it's already updated
How is that possible?

Based on #Grigor Hakobyan comments, I started digging into the web and maybe he is correct.
I would tell you to read this article.
https://davidnix.io/post/stop-using-nsnotificationcenter/
It's looks like the NSNotificationCenter isn't a really good option, and you can use the Delegate Pattern to this case, which looks like a better option
Have a nice day

Using NSNotificationCenter is a very bad solution, just reload your tableView(collectionView) when user select any tab and use advanced OOP principles

Assuming you're using a segmented control like in the examples you showed, you should have a function that calls whenever you select a segment. In that function you can either reload the data or the tableviews.
#IBAction func indexChanged(sender: UISegmentedControl) {
tableView.reloadData()
}

Related

Observe backForwardList changes of WKWebview

To explain my problem I would like to start with the fundamentals of my project.
We are building an app which employs a web view which loads a lot of different websites (web apps) to form our app package. Those web apps are made with different web tech like ruby or ember/react (single page web app). The later change urls via push state which is problematic for the webviews WKNavigationDelegate as it doesn't recognise any of those url changes. If you load normal http requests (like old rails pages) then everything is fine and well.
In order to know on which page the user is at any time I created a user script which tapped into the pushsstate js prototype and messaged back the url change to the iOS app and even though this is A solution its in my eyes incredibly hacky. So I have been looking for alternatives and I came across the WKWebView.backForwardList which actually records all those push state changes.
The issue I have now is how do I monitor/observe the backForwardList for changes in lets say the currentItem? You can't use KVO to do so as these properties don't support it.
I did however found a possible solution by observing the webview.scrollView.contentSize which for some reason will trigger every time something changes on the screen. It's odd that this observer is fired for every single animation which is running on the screen its almost as if its called on pixel changes of the scrollview. Our web apps are animating all the time as they build with canvas elements for games which means the observer is called a lot and don't feel comfortable to have this running all the time.
Do you know a nicer/neater way to keep track of the changes WKWebView.backForwardList items.
Cheers Thomas
I found the solution which seems obvious but wasn't at the time
// Add observation.
urlObservation = webView?.observe(\.url, changeHandler: { (webView, change) in
print("Web view URL changed to \(webView.backForwardList.currentItem?.url.absoluteString ?? "Empty")", webView.scrollView.contentSize.width, webView.scrollView.contentSize.height)
})
This seems to track the url changes even though the navigation delegate are NOT triggered in any way.

How to Manage state between tabs in Flutter App

I am using TabBar in my application where I need to get Input in first tab and show
output based on some calculation on other tab.
I am able to get input in first tab but when I click on second tab, my state is lost. I am not sure if I have to make it a Stateful widget at root level.
I am relatively new in Mobile App. Can someone help me out here?
EDIT:
Now I am able to achieve what I said above, but when I am trying to access the list of items from first tab, it throws null exception in second tab?
I solved the above problem using AutomaticKeepAliveClientMixin as described in the answer below.
I think what you may be after is AutomaticKeepAliveClientMixin. I always add that to my screen widgets within TabBarView. This way when a user enters data into fields in one tab and navigates to other tabs and back the data is still there as you would expect.
Then when the user performs an action like "save" I deal with state management (BLoC etc).
You may want to use architecture for managing and sharing states. There are many approaches to manage state:
InheritedWidget to pass app state down the widget hierarchy
Scoped model library to hold app state and notify Widgets of Updates
Redux library to manage app state and update Widgets
Business Logic Components (BLoC)
Check out this article. Check this GitHub repository with different architecture examples

Keeping a WKWebView and it's UIViewController in the background running and accessible from multiple ViewControllers

Background: In order to make web requests to an API endpoint, I need to scrape a website and retrieve a token every 25-30 seconds. I'm doing this with a WKWebView and injecting some custom JavaScript using WKUserScript to retrieve AJAX response headers containing the token. Please focus on the question specifically and not on this background information - I'm attempting this entirely for my own educational purposes.
Goal
I will have different 'model' classes, or even just other UIViewControllers, that may need to call the shared UIViewController to retrieve this token to make an authenticated request.
Maybe I might abstract this into one "Sdk" class. Regardless, this 'model' SDK class could be instantiated and used by any other ViewController.
More info
I would like to be able to call the UIViewController of the WKWebView and retrieve some data. Unless I re-create it every 25 seconds, I need to run it in the background or share it. I would like to be able to run a UIViewController 'in the background' and receive some information from it once WKWebView has done it's thing.
I know there are multiple ways of communicating with another ViewController including delegation and segueing. However, I'm not sure that these help me keep the view containing the WKWebView existing in the background so I can call it's ViewController and have it re-perform the scrape. Delegation may work for normal code, but what about one that must have the view existing? Would I have to re-create this WKWebView dynamically each time a different model, or view controller, were to try and get this token?
One post suggests utilising ContainerViewControllers. From this, I gather that in the 'master' ViewController (the one containing the other ones), I could place the hidden WKWebView to do it's thing and communicate to the child view controllers that way via delegation.
Another post suggests using AppDelegate and making it a shared service. I'm completely against using a Singleton as it is widely considered an anti-pattern. There must be another way, even if a little more complex, that helps me do what I want without resorting to this 'cheat'.
This post talks about communicating between multiple ViewControllers, but I can't figure out how this would be useful when something needs to stay running and executing things.
How about any other ways to do this? Run something in a background thread with a strong pointer so it doesn't get discarded? I'm using Xcode 9.2, Swift 4, and iOS 11. As I'm very new to iOS programming, any small code examples on this would be appreciated.
Unfortunately, WKWebView must be in the view hierarchy to use it. You must have added it as a sub view of an on-screen view controller.
This was fine for me. I added this off-screen so it was not visible. Hidden attribute might have worked as well. Either way you must call addSubview with it to make it work.
There are some other questions and answers here which verify this.
Here is a way if you don't wish to use a singleton.
1- In the DidFinishlaunchingWithOptions, Make a timer that runs in the background and call a method inside the app delegate Called FetchNewToken.
2- In FetchNewToken, make the call needed and retrieve the new token (you can use alamofire or any 3rd library to make the call easier for you).
Up on successfully retrieving the token, save it in NSUserDefaults under the name upToDateToken
You can access this token anywhere from the application using NSUserDefaults and it will always be up to date.

VSTS/TFS Extension - Reflect changes in Grid/Board without refreshing entire page

I've written an extension for VSTS/TFS which adds a context menu for creating child work items.
The creation of the work items works well, but the change is not reflected in the Grid/Board until I perform a Refresh of the entire page.
Is there a way to refresh just the affected work items (somewhat similar to the refresh performed by the '+' menu item)?
There isn't any way to achieve this. If you open two pages and click "+" button to add two different child workitems from the two pages in the same time, you will find that the affected work item is not real refreshed, it just show the new added one. And you cannot control the behavior on Grid/Board either since the VSTS extensions are hosted in iframe which is cross-origin.
As far as I know this is currently not possible.
I struggled with that question for quite some time before I gave up and just told my users to hit F5 after creating the new work items. The NavigationService is the best alternative i know of.
For your specific case, this doesn't help you. However, if anyone runs across this question looking for ways to refresh a work item, you can use the work item form service method "refresh":
https://www.visualstudio.com/en-us/docs/integrate/extensions/reference/client/api/tfs/workitemtracking/services/workitemformservice#refresh
This service is a means to interact with the currently active work item form. So, this refresh will work on a work item that the user has opened.

Saving and Filtering Favourites from a UITableViewController without Core Data

I am building a simple informational based app that provides the users with built in Leaflets and Images to view, on a variety of topics. It's a UITabBar -based application where the first tab is a list of Leaflets, the second is a list of Videos and the third is a list of Languages. Each tab is represented by a UITableViewController.
I would like to set up a favouriting mechanism where users can swipe across any leaflet or video in the UITableViewCell and "favourite" it. Whichever they favourite will then get added to the 4th tab called (unimaginatively), Favourites.
I'm not using Core Data with this application because there's no real need to do that and because I'm quite new to this concept, I'm wondering on the best way to save up to 50 favourites. How would I store this? Would I use something like a NSUserDefault for example?
It's a broad question because I've looked online and I'm not quite sure how to approach this.
I would really appreciate if anyone had any guides or thoughts on how to firstly save this and secondly, how to fetch the favourites for the favourites tab. Would/Could I use something like a NSFetchedResultsController even though I'm not using Core Data?
Should I just use Core Data with this, to save the favourites?
Any thoughts on this would really be appreciated.

Resources