Session 6
splitting up is easy to do (with a split view controller)
Session Materials
- Session 6 Slides
Resources
- AutoLayouts
- Mysteries of Auto Layout, Part 1 – WWDC 2015 – Videos – Apple Developer [Implementing UI Designs in Interface Builder
- WWDC 2015 – Videos – Apple Developer](https://developer.apple.com/videos/play/wwdc2015/407/)
- AstroLayout: Building Adaptive UI with Auto Layout – Objective-C
- What’s New in Auto Layout – WWDC 2016 – Videos – Apple Developer
- Mysteries of Auto Layout, Part 2 – WWDC 2015 – Videos – Apple Developer
- UISplitViewController
- UISplitViewController
- WWDC 2015 Video Session 216
- iOS Day by Day
- iOS Concurrency
- Advanced NSOperations WWDC 2015
- Crazy Swift Custom Operator
- Designated Initializers
- Adaptive Layout
- Appearance Proxy in UIKit
- NSUserDefaults
- Apple Developer Documentation
Assignment
In this assignment, “Go Ask a Duck”, you will create an instant answers search engine using the DuckDuckGo Instant Answer API. The application will make use of a UISplitViewController
for the application’s main interface and use NSFoundation
and native Swift networking classes. This assignment will require the use of both Storyboards and programmatic interface design.
Project Setup
- Use the Master-Detail Application template provided by Xcode as the starting point for your application. You should adapt it accordingly to meet the requirements of the assignment.
- Make the application Universal by using an adaptive Storyboard.
- Use
UIAppearance
proxy to customize the appearance of your application in the following ways:- Change the color of the
UINavigationBar
. You can select the color. - Change the tint color of the
UINavigationBar
. You can select the color.
- Change the color of the
The View Controllers
MasterViewController
- The
MasterViewController
should have aUITableView
that is filled with the results from the Duck Duck Go query. - Include a
UISearchBar
in the table view’s header. You can add this in Storyboard or programatically. The search bar should provide the text for the Instant Answer API search query. This data should serve as theMasterViewController
’s tableview’sdataSource
. - Use the following URL to retrieve the results in JSON format.
http://api.duckduckgo.com/?q=<QUERY TERM>&format=json&pretty=1
For example:
http://api.duckduckgo.com/?q=tesla&format=json&pretty=1
- You should used the
RelatedTopics
key to retrieve an array of dictionaries of the results.
- The table view should use a custom cell that displays the
FirstURL
and theText
field for the snippet. You will notice that theText
has an odd issue with the formatting where it appends the search term to the front of the snippet. You may optionally (it is not required), use the text in theResult
field and strip out the HTML portion using some Swift string processing:
// The result from DDG
let result = "<a href=\"https://duckduckgo.com/Apple\">Apple</a>A deciduous tree in the rose family best known for its sweet, pomaceous fruit, the apple."
// Use componentsSeparatedByString to split the string.
let text = result.componentsSeparatedByString("</a>")
let cleanSnippet = text[1]
- The table cells should use autoresizing to adjust to fit the length of the text snippet.
DetailViewController
- The
DetailViewController
should display the link in aUIWebView
(see Figure 3) when tapping on a cell from theMasterViewController
. test
- Add a toolbar that holds a Favorite This Article button. Tapping on this button should save the relevant link information to
NSUserDefaults
. You will need to save enough metadata about the search results to be able to load the url from the bookmarks list later on. You should save the search term as well. - Add a
UIBarButton
to the navigation bar that has a segue to aBookmarkViewController
. This segue should of type Present As Popoverand can be set in the Storyboard.
BookmarkViewController
- The
BookmarkViewController
should display a table view of links that have been selected as favorites by the user. The data source should be stored inNSUserDefaults
from users interactions when previously viewing the page.
- The table view should be editable, allowing users to delete articles from the list.
- The view controller should be displayed as a popover, which should be defined by the segue type in the
DetailViewController
. Set thepreferredContentSize
so that it is 500pt x 500pt. See Figure 5.
- Tapping on a article in the list should dismiss the popover view controller and load the URL into the web view. To pass back the URL to the web view, you should create a custom protocol, named
DetailBookmarkDelegate
that communicates with the web view. The protocol needs to define only a single methods:
protocol DetailBookmarkDelegate: class {
func bookmarkPassedURL(url: String) -> Void
}
- Ensure that the
DetailViewController
conforms to this protocol.
extension DetailViewController: DetailBookmarkDelegate {
func bookmarkPassedURL(url: String) {
// Load the passed in URL to the webview
}
}
- Ensure that the
BookmarkViewController
has a delegate property that conforms to the protocol. This provides the connection between the objects that will communicate. Note that declaring you delegate property as weak prevents a retain cycle where two objects (BookmarkViewController
andDetailMasterView
) have a strong reference to the object and it will never be released from memory (ie a leak).
weak var delegate: DetailBookmarkDelegate?
Networking
- Create a singleton class named
SharedNetworking
that will handle your API requests. In this class, useURLSession
to retrieve the RSS feed. - Use the
JSONSerialization
class to process the data. Your method should use a closure based completion handler. You may (and should) adapt your networking code from previous assignments.
- Your singleton class should use the
networkActivityIndicatorVisible
property ofUIApplication
to activate the system activity indicator in the status bar when a networking operation is happening. - Anytime there is a networking operation (either from your own or from the
UIWebView
) you should indicate this to the user.- Create a custom
UIView
that functions as a loading screen that appears wheneverUIWebView
is loading content. UseUIActivityIndicator
in the interface. - You should use the
UIWebView
delegate methods to monitor the loading progress (See Figure 1).
- Create a custom
- There may be times when the data from DuckDuckGo is not available. It could be an issue with the server or a problem of bad connectivity from a device. There are many additional reasons why this could fail, but the only think that matters is your users will not be happy. You should inform the users if the request fails so that they understand what is happening with the application.
- Present an
UIAlertViewController
to the user when the DuckDuckGo API request fails. The exact wording of the alert is up to you. - There are several different points of potential failure in the networking code where this should be tested for. You do not have to differentiate the type of failure to the user, just a simple message to inform them the request did not work.
Functionality
- On the application’s very first launch, use the query “apple” so that your users have something to look at.
- Save the last query in
UserDefaults
and preload it the query in theMasterViewController
when the application is launched to ensure that there is something loaded whenever the user uses the application. - Save the last viewed article in
UserDefaults
and preload it in theUIWebView
when the app is launched. - When a user taps on an article, it should load in the web view.
- The user can save their favorite articles by tapping on the button in the toolbar.
- Tapping on the Bookmark button should present a popover style view controller with a table of favorite articles (loaded from
UserDefaults
. The user should be allowed to delete articles from the list. - Tapping on article should dismiss the popover and load the article into the webview.
- The application’s
UISplitViewController
functionality should work correctly.- In portrait on a iPad, only the
DetailViewController
should show and display a button in the navigation bar to show theMasterViewController
. - In landscape orientation, both view controllers should be visible.
- In portrait on a iPad, only the
- Add an image of a star (or similar favorite image) on the
DetailViewController
to let the users know they are reading a favorite article. UseAdaptive Layout
techniques to ensure that the star can be seen at all times.
Grading
The application should compile with no errors or warnings and perform all described behaviors. If the app does not compile you will receive a 0. Feel free to explore additional enhancements to improve the appearance or functionality of the application.
The 11th point will be awarded for applications that implement a “Night” mode for their application. Combining many of the techniques from this assignment, you should be able to invert the color palette to make the application easier to use in a dark setting.
- Add a button to the navigation bar in each view controller for “Night” mode. Tapping on this button should toggle the state between normal and night mode.
- If the application is in “Night” mode, the tables background color should be dark and the text a light color.
Grading
The application should compile with no errors or warnings and perform all described behaviors. If the app does not compile you will receive a 0. Feel free to explore additional enhancements to improve the appearance or functionality of the application.
Due Date
Assignment 6 is due February 20, 2017 at 5:29pm.