Q-1 What Is Parsing? Explain XML Parsing and JSON Parsing With Example. OR Explain JSON Parsing With Example
Q-1 What Is Parsing? Explain XML Parsing and JSON Parsing With Example. OR Explain JSON Parsing With Example
Q-1 What Is Parsing? Explain XML Parsing and JSON Parsing With Example. OR Explain JSON Parsing With Example
import Foundation
let data: Data // received from a network request, for example
let json = try? JSONSerialization.jsonObject(with: data, options: [])
Although valid JSON may contain only a single value, a response from a web
application typically encodes an object or array as the top-level object.
You can use optional binding and the as? type cast operator in an if or guard
statement to extract a value of known type as a constant.
To get a Dictionary value from a JSON object type, conditionally cast it as [String: Any].
To get an Array value from a JSON array type, conditionally cast it as [Any] (or an array
with a more specific element type, like [String]).
You can extract a dictionary value by key or an array value by index using type cast
optional binding with subscript accessors or pattern matching with enumeration.
Swift’s built-in language features make it easy to safely extract and work with JSON
data decoded with Foundation APIs — without the need for an external library or
framework.
Creating Model Objects from Values Extracted from JSON
Since most Swift apps follow the Model-View-Controller design pattern, it is often
useful to convert JSON data to objects that are specific to your app’s domain in a
model definition.
For example, when writing an app that provides search results for local restaurants,
you might implement a Restaurant model with an initializer that accepts a JSON
object and a type method that makes an HTTP request to a server’s /search endpoint
and then asynchronously returns an array of Restaurant objects.
Consider the following Restaurant model:
import Foundation
struct Restaurant {
enum Meal: String {
case breakfast, lunch, dinner
}
A Restaurant has a name of type String, a location expressed as a coordinate pair, and
a Set of meals containing values of a nested Meal enumeration.
Here’s an example of how a single restaurant may be represented in a server
response:
{
"name": "Caffè Macs",
"coordinates": {
"lat": 37.330576,
"lng": -122.029739
},
"meals": ["breakfast", "lunch", "dinner"]
}
extension Restaurant {
init?(json: [String: Any]) {
guard let name = json["name"] as? String,
let coordinatesJSON = json["coordinates"] as? [String: Double],
let latitude = coordinatesJSON["lat"],
let longitude = coordinatesJSON["lng"],
let mealsJSON = json["meals"] as? [String]
else {
return nil
}
meals.insert(meal)
}
self.name = name
self.coordinates = (latitude, longitude)
self.meals = meals
If your app communicates with one or more web services that do not return a single,
consistent representation of a model object, consider implementing several initializers
to handle each of the possible representations.
In the example above, each of the values are extracted into constants from the passed
JSON dictionary using optional binding and the as? type casting operator.
For the name property, the extracted name value is simply assigned as-is.
For the coordinate property, the extracted latitude and longitude values are
combined into a tuple before assignment.
For the meals property, the extracted string values are iterated over to construct a Set
of Meal enumeration values.
XML Parsing
Generally, when you parse an XML document most of the processing involves
elements and things related to elements, such as attributes and textual content.
Elements hold most of the information in an XML document.
To parse XML Data declare following variable in your class.
var parser = NSXMLParser()
var posts = NSMutableArray()
var elements = NSMutableDictionary()
var element = NSString()
var title1 = NSMutableString()
var date = NSMutableString()
Here parser is the object, which is used to download and parse the xml file.
Post is object of mutable array used to store feed data.
Element is a mutabledictionary which contains the data of feed like title and date
separately. Title1 and date used to store string data of feed.
Now from viewDidLoad method calling beginParsing method in that doing
initialization of parser object, set NSXMLParserDelegate and then start XML parsing.
func beginParsing()
{
posts = []
parser = NSXMLParser(contentsOfURL:(NSURL(string: "http://images.
apple.com/main/rss/hotnews/hotnews.rss"))!)!
parser.delegate = self
parser.parse()
tbData!.reloadData()
}
To implement the parser delegate method have to set delegate in class as shown
below. It informs the compiler that ViewController class implements the
NSXMLParserDelegate.
class ViewController: UIViewController, NSXMLParserDelegate
During parsing, when parser finds any new element it calls the below delegate
Ashok G. Badresiya, CE Department | 2180714-iOS Programming 4
IMP Questions
method. In this method allocate variable when parser find the item element.
func parser(parser: NSXMLParser, didStartElement elementName: String,
namespaceURI: String?, qualifiedName qName: String?, attributes
attributeDict: [String : String])
{
element = elementName
if (elementName as NSString).isEqualToString("item")
{
elements = NSMutableDictionary()
elements = [:]
title1 = NSMutableString()
title1 = ""
date = NSMutableString()
date = ""
}
}
After that when it finds new character it calls the below delegate method. In this
method append all character in mutable string for particular element.
func parser(parser: NSXMLParser!, foundCharacters string: String!)
{
if element.isEqualToString("title") {
title1.appendString(string)
} else if element.isEqualToString("pubDate") {
date.appendString(string)
}
}
When parser finds the end of element it calls the below delegate method. In that just
store the feed data in dictionary and then add that dictionary in array.
func parser(parser: NSXMLParser!, didEndElement elementName: String!,
namespaceURI: String!, qualifiedName qName: String!)
{
if (elementName as NSString).isEqualToString("item") {
if !title1.isEqual(nil) {
elements.setObject(title1, forKey: "title")
}
if !date.isEqual(nil) {
elements.setObject(date, forKey: "date")
}
posts.addObject(elements)
}
}
View Objects
A view object is an object in an application that users can see.
A view object knows how to draw itself and can respond to user actions.
A major purpose of view objects is to display data from the application’s model
objects and to enable the editing of that data.
Despite this, view objects are typically decoupled from model objects in an MVC
application.
Because you typically reuse and reconfigure them, view objects provide consistency
between applications.
Both the UIKit and AppKit frameworks provide collections of view classes, and
Interface Builder offers dozens of view objects in its Library.
Communication: View objects learn about changes in model data through the
application’s controller objects and communicate user-initiated changes—for
example, text entered in a text field—through controller objects to an application’s
model objects.
Controller Objects
A controller object acts as an intermediary between one or more of an application’s
view objects and one or more of its model objects.
Controller objects are thus a conduit through which view objects learn about changes
in model objects and vice versa.
Controller objects can also perform setup and coordinating tasks for an application
and manage the life cycles of other objects.
Communication: A controller object interprets user actions made in view objects and
communicates new or changed data to the model layer. When model objects change,
a controller object communicates that new model data to the view objects so that
they can display it.
Example:
Imagine you have a UIViewController subclass that wants to know the list of WWDC
attendees this year.
To achieve this, it makes use of a controller class. Since Apple’s been preaching that
we should always start with a protocol, you’ll do that here:
enum UIState {
case Loading
case Success([Attendee])
case Failure(Error)
}
self.attendeesHandler = attendeesHandler
super.init(nibName: nil, bundle: nil)
}
attendeesHandler.fetchAttendees()
}
This approach will put the fetching action on the UIViewController side, but leave the
response handling to the WWDCAttendeesUIController:
extension WWDCAttendeesUIController: WWDCAttendesDelegate {
switch(state, newState) {
func loadingToLoading() {
view.addSubview(loadingView)
Ashok G. Badresiya, CE Department | 2180714-iOS Programming 11
IMP Questions
loadingView.frame = CGRect(origin: .zero, size: view.frame.size)
}
Note in Swift the sender object is of type AnyObject, this is the equivalent of the id
object in Objective-C. Next, implement the buttonTapped function.
@IBAction func buttonTapped(sender: AnyObject) {
let alertController = UIAlertController(title: "Alert", message:
"Hello, world!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style:
UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
Our Table View will have 3 rows according to the count method of the Array class.
Next, implement the tableView:cellForRowAtIndexPath function
func tableView(tableView: UITableView!,
cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
let cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.
Default, reuseIdentifier:"cell")
cell.textLabel?.text = tableData[indexPath.row]
return cell
}
Each Row will have a default tableview-style and will have the values of our tableData
array.
In Swift the intializer method names are truncated, so the initWithStyle: reuse
Identifier method from Objective-C is named style:reuseIdentifier in Swift.
Build and Run the project.
It will show Table View with the rows filled.
The table view with three rows namely: one, two, three will generated.
Picker
The picker view is a slot-machine view to show one or more sets of values.
Users select values by rotating the wheels so that the desired row of values aligns
with a selection indicator.
The user interface provided by a picker view consists of components and rows.
A component is a wheel, which has a series of rows at indexed locations on the wheel.
Example:
Open Xcode and create a new Single View Application.
Go to the Storyboard, drag a Picker View from the Object Library to the top of the
View Controller inside the Storyboard.
Select the Picker View and set the proper location where you want to put the picker.
The Picker View must conform to the UIPickerViewDataSource and
UIPickerViewDelegate protocol.
Ctrl-click the Picker View and drag from the dataSource Outlet to the View Controller
in the Document Outline.
Repeat this step for the delegate Outlet.
We must provide the Picker View with values.
Add the following array in the ViewController class in the ViewController.swift class:
var colors = ["Red","Yellow","Green","Blue"]
The colors array will be the data source for our Picker View.
The UIViewDataSource protocol requires delegate methods to define the number of
components and rows of a picker.
Implement these methods:
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
In that code, s is a Swift String and s2 is a Swift String, but the capitalized property
actually belongs to Cocoa.
In the course of that code, a Swift String has been bridged to NSString and passed to
Cocoa, which has processed it to get the capitalized string; the capitalized string is an
NSString, but it has been bridged back to a Swift String.
In some cases, Swift may fail to cross the bridge implicitly for you, and you will need
to cross the bridge yourself by casting explicitly.
For example, if s is a Swift string, you can’t call appendingPathExtension on it directly:
let s = "MyFile"
let s2 = s.appendingPathExtension("txt") // compile error
In above code, the URLForResource() function search for the pdf file with given name
in first argument and second argument is extension of file means ‘pdf’ in our case.
URLForResource() function return the path of the desired pdf and we have stored the
path in the url variable.
We have created a PDFView object with desired width and height and given name it
to view.
View, the object of PDFView, will show our desired pdf into view when it will called.
Both build upon the same kernel, but OS adds Core Services, Application Services and
QuickTime, as well as the Classic, Carbon, Cocoa, and Java (JDK) application
When you remove an object from a mutable collection, the collection releases it.
So, the second line of that code involves an implicit release of the object that used to
be element 0 of myMutableArray.
If this reduces the object’s retain count to zero, it will be destroyed.
The pointer obj will then be a dangling pointer, and a crash may be in our future when
we try to use it as if it were a real object.
With ARC, however, that sort of danger doesn’t exist. Assigning a reference type
object to a variable retains it!
But we did assign this object to a variable, obj, before we removed it from the
collection. Thus that code is perfectly safe, and so is its Swift equivalent:
let obj = myMutableArray[0]
myMutableArray.removeObject(at:0)
// ... safe to refer to obj ...
The first line retains the object. The second line releases the object, but that release
balances retain that was placed on the object when the object was placed in the
collection originally.
Thus the object’s retain count is still more than zero, and it continues to exist for the
duration of this code.