I am writing a news application for iOS using MonoTouch. The data comes via an OData web sevice.
I have a singleton class called NewsFactory which is responsible for querying the OData feed. Now in the ViewDidLoad method I am retrieving the list of news articles and binding it to the table view.
However - I am not sure how to refresh this every time the app is launched. I don't care much for "pull to refresh". All I want to make sure is that every time the app is launched (from scratch or activated again) that the call to the web service is made to make sure I show the latest info.
In addition, I want to cover for the scenario where the network connectivity is lost when the app is launched and I notify the user. The use closes the app (suspend) and let's say the network connectivity returns - If the user opens the app again, I would like to make sure that I show the latest news articles.
I am building the view hierarchy programmatically. I have navigation controllers and a tab bar controller with 5 tabs.I am targeting iOS 5.
I tried playing with OnActivated and ViewWillAppear and they don't do exactly what I need to do. This is a very common need for any iOS app so there must be a solution - I am new to this so any help is appreciated.
Well you have to think, in general, if you call a method that loads from one source (let's say a text file that has data in it), then you change up the source (change text data), but call the same method when the class is loaded, then the new data will appear when the new class is loaded.
Like for example:
- (void) loadView {
NSString *testString = [NSString stringWithContentsOfFile:filePath];
textView.text = testString;
}
This example shows the setting of text in a file to a UITextView instance. If you load it the first time and the file contained the contents of "Hi", then the textView will say hi. If you change it, then call the same method, then it will show your changed text the second time you load the app.
The point is that if you change data, then call the same method, then you'll see a difference. Unless you're working with a database.
I'd give you a better example if you provide sample code.
EDIT: Not sure if your custom class comes with this function, but it is included in the regular UITableView class:
[tableView reloadData];
You can call that after your array changes internally.
Related
I build chat app using Firebase API right now. I wan't to make preload icons like on facebook screenshot. I thought i can create empty images and label fields and fill them after content loaded, but i don't know how to check if all data loaded from DB. How i can do that in correct way?
This is where i want to place objects
Install ListPlaceholder this lib.
import ListPlaceholder
To show the loader, start showing this from start
tableView.showLoader()
To hide the loader, end showing after data has been loaded
tableView.hideLoader()
Please refer this may get help.
https://github.com/malkouz/ListPlaceholder
Facebook has it's own library called Shimmer. To use this on tableview, you can follow this StackOverflow question answer.
You'll just have to create the UIView you want to animate and above that you'll have to add your FBShimmeringView. At the end set shimmeringView.shimmering = true to start shimmering
To hide the loading use tableView.hideLoader()
ListPlaceholder helped me to resolve the issue. All that I did was added the ListLoader.swift file to my project and added tableView.reloadData(), tableView.showLoader() in viewDidAppear in the tableView where I wanted to show loading.
( ListLoader.swif uses visibleCells to determine the number of rows on which the loading should be shown. In my applications, visibleCell's count was incorrect on calling tableView.showLoader() method in viewDidLoad )
I have recently started to learn iOS with obj-c from "iOS Programming The Big Nerd Ranch Guide 4th Edition". This edition was released in 2014 and is written with Xcode 5.
I am trying to make a simple app with two buttons and two labels. The labels are connected to two arrays and when a button is pressed an object from the corresponding array is shown in the corresponding text label (it's the Quiz app in chapter 1).
I created the project as a Single View app in Xcode 6, and put all my objects in the view controller class. I have two labels two buttons two arrays and an int to keep track of the object that has to be displayed from the array.
In the book it says that I should initialize the arrays in the initWithNibName method. I tried that but for some reason it never gets called. So I changed the initialization of the arrays to the init method. They initialize fine but when they are called from another method they are nil. Do you have any idea why this is happening?
The second issue I'm having is that I can't manage to get the contents of the storyboard on screen. It says that I'm supposed to make an instance of the ViewController inside the AppDelegate and make it the root window controller but all I get is a white window (or black in case I don't set the color).
UPDATE: I changed the intialization of the arrays from the init method to the viewDidLoad method and now they seem to be working fine. Nothing on the screen though.
It sounds like you're initializing your UIViewController from the app delegate AND a storyboard. If you create a new project in XCode, a "Single view application", you won't have to touch the app delegate at all in order to get something on the screen.
I believe both your problems are related to this, since it sounds like you're seeing an empty UIViewController on the screen (the one you create in the app delegate)
As for the initialization of your array, viewDidLoad is a popular place to do this.
If you are using storyboards, the method initWithNibNameOrNil will not be called. In the BNR book, it teaches you to use XIB files, which do use this method. If you are trying to follow the tutorials, I would suggest using XIB files.
For use of a book, I would suggest downloading whatever version of Xcode is being used for that book -- otherwise you will be running into a lot of confusing problems while learning.
If you would like to download previous version of Xcode, refer to this post:
How to download Xcode DMG or XIP file?
I have a basic watchkit app that loads a page based navigation of 3 interface controllers. This works well, but I'd then like to trigger an action to remove the page-control and essentially revert back to the original InterfaceController that was present when the app first loads.
// load page based control, with 3 views. this works ok
[WKInterfaceController reloadRootControllersWithNames:#[#"pageController1",#"pageController2",#"pageController3"]
contexts:#[#"data1",#"data2",#"data3"]];
// attempt to reload original interface controller, identified by storyboard id
[WKInterfaceController reloadRootControllersWithNames:#[#"myInterfaceController"] contexts:#[#{}]];
The page based navigation remove, the original navigation loads after a short spinner. However it fails to function correctly and original Actions result in this error.
Extension[6766:123665] *********** ERROR
-[SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier for interfaceControllerID:(null) not found
Is there a better way to cleanly reload the original InterfaceController?
EDIT, 2/19
It seems there are some other actions that are causing this error too. For instance, if segue to a second InterfaceController and then popController to get back, the error often appears. It is always related to a secondary call to this function.
[WKInterfaceController reloadRootControllersWithNames: contexts:]
EDIT2, 3/18
As previously mentioned, this is reproducible 100% of the time by doing the seguePush, the popController, then attempting to reloadRootControllersWithNames.
If the seguePush/popController is not done beforehand, then the reloadRootControllersWithNames will work fine.
This situation seems to be in addition to the multi->single-multi instance of this bug.
This is actually not a bug because according to Apple:
You cannot combine hierarchical and page-based interface styles. At design time, you must choose the style that best suits your app’s content and design for that style.
So unfortunately, we can't mix Hierarchical and Page-based navigation patterns within the same Watch app.
Just one of many limitations we have to deal with when developing apps for Watch
This is a bug in WatchKit in Xcode 6.2 Beta 5. Please dupe the following radar on Apple's Bug Reporting System to help raise the priority to get this fixed.
In the meantime, a workaround that I've found can be found on the dev forums. What you can do is add a dummy interface controller to any single interface controller page set so you always have two. This will fix the error until Apple get's the bug fixed (hopefully in Beta 6). Please dupe!
I was able to solve my instance of this problem by not using popController on a pushed view controller. Instead I use a reloadRootControllersWithNames in place of the popController.
How this allows both push and paging, via an example:
Push a view controller
reloadRootControllersWithNames to return to the original controller. (The transition is not quite as animated, but is sufficient)
Create page based view controller.
reloadRootControllersWithNames to return to the original controller
Repeat 1 or 3 as needed.
This eliminates the error at the cost of non-animated popControllers, and allows partial pushing and paging. It would not allow more complex push navigation though.
There may be a better method of navigating to a sub interface controller without a push call, but I'm not aware of it on the watch yet.
None or the answers above worked for me. This problem began when I changed the icon names for the app and the watch app name. I solved it like this:
1) Click on your Watch app Target > Capabilities > make sure app Group
is in ON.
2) Make sure the App Group is selected.
3) Clic on the circled arrow Refresh icon (this will apparently just
refresh this thing if you already had it)
4-Repeat steps 1-3, but for your Watch App EXTENSION target too.
5-Click on the Scheme button (on the right side of the STOP button),
and clic on Edit Schemes.
6-Click Run > Info 7-In executable select your target (Actually it
should already be selecting but opening this window seems to
refresh the option, and wipe the error)
Apparently all these things above are not updated automatically when you change the icon name (Target names) and you have to go to those menus and open them to refresh them manually. Shame on Apple perhaps?
I'm working on a today view extension with some custom view elements which I don't set up in interface builder.
Now I'm wondering where the right point in the lifecycle is to init the widget content.
I read about updating the content in widgetPerformUpdateWithCompletionHandler so I implemented a check for new updates which should about the view.
But my observations showed me that the method is called before viewDidAppearand so there is no view to update.
Also I tought the widget stays in memory for a while so that I can have a certain object in widgetPerformUpdateWithCompletionHandler whose content I can update and use in viewDidAppear but this isn't the case (it loads every time)
So what is the correct way: write content to disk in the widgetPerformUpdateWithCompletionHandler, can I depend on something that is in memory or just ignore and refresh on every load?
In TodayViewController.m -viewDidLoad() method is called each time you open notification. So when ever you check Today widget it will call -viewDidLoad(). So you do your customisation in -viewDidLoad(). Unless you don't want to check previous state.
Straight from a blog which helps a create Today widget with real time data:
Creating today widget
Caching
We can take advantage of NSUserDefaults to save the calculated used space between launches. The lifecycle of a widget is short so if we cache this value, we can set up the user interface with an initial value and then calculate the actual value.
Edit:
From Apple documentation it state that
To help your widget look up to date, the system occasionally captures snapshots of your widget’s view. When the widget becomes visible again, the most recent snapshot is displayed until the system replaces it with a live version of the view.
It is also state that from Notification center, We can get widget details of state and snapshot.
Not sure with this, but it state that below method is used by both widget and containing app to check its content. There is no much details about how to get widget snapshot.
func setHasContent(_ flag: Bool,
forWidgetWithBundleIdentifier bundleID: String!)
NCWidgetController setHasContent
Edit 2: Use of NSUserDefaults in extension:
You have two .entitlements files, one for host app and second for the extension app, add below key in both files
<key>com.apple.security.application-groups</key>
<array>
<string>group.YourExtension</string>
</array>
You see the value for key is group.YourExtension it is shared
common key for both host app and extension app
Save your data using group.YourExtension in NSUserDefaults
I'm attempting to create an introduction to my iOS app. So I've created a few view controllers that are shown in the beginning of the app. On the last introduction view controller there is a button which brings you to "the actual app".
How do I make it so when that button is clicked the app launches with a different view controller.
If someone could walk me through the steps and be very detailed I would appreciate it as I'm a beginner iOS developer.
One option is to store whether "view intro" is set to true/false & set this value in NSUserDefaults. Check that value when the app starts & put an if/else to load the appropriate VC. You might want to make the button "skip" intro entirely & set this value. People generally get annoyed w/long intros & want to use your app. See this answer about NSUserDefaults.
I am assuming you are creating an "app tutorial" type of introduction. Also assuming that you only want this to occur the first time the user uses the app, then go directly to the app every other time.
I would store a didWatchTutorial BOOL value in the NSUserDefaults.
This would also need to include an if/else statement in the opening view controller of your app, which controls (based on this BOOL value) if the user should be shown the tutorial:
if (didWatchTutorial) {
//GO STRAIGHT TO APP
} else {
//SHOW TUTORIAL
}