Property in Swift - Computed property | Property Observers (WillSet & DidSet)

   Computed property -  Computed properties are part of a property type in Swift.  Stored properties are the most common which save and return a stored value  Computed properties calculate (rather than store) a value. A computed property provides a getter and an optional setter to indirectly access other properties and values. Computed property in swift is an interesting topic as you can write code inside a property in swift. Computed properties are provided by classes, structures, and enumerations but stored properties are provided only by classes and structures. This computed property swift tutorial has some tips on how to use the computed property in the right way and avoid the common mistakes that swift programming beginners do while computed property. Example :- Computed property A Calculate Simple Intrest struct CalculateLoan {      var amount : Int      var rate : Int      var years : Int      var simpleInterest: Int {          get {              return ( amount * rate

Parse XML in iOS with Swift 4.0 with A SOAP Web Service Apple RSS News

A Simple XML Parsing Example in ios with Swift 4.0. 
Parse XML in iOS with Swift 4.0


ASMX - SOAP-XML(Simple Object Access Protocol - Extensible Markup Language)
SOAP - Simple Object Access Protocol itis a xml-based messaging protocol for exchanging information among computer
"ASMX provide the ability to build service that send message using the SOAP"

  • SOAP is communication via internet
  • SOAP can extend HTTP for XML messaging
  • Data transfer for web service

"XML stands for Extensible Markup Language. XML is a markup language much like HTML. XML was designed to store and transport data. XML was designed to be self-descriptive."
its defines a set of rules for encoding documents in a format human-readable and machine-readable.

In this tutorial parse xml web service(apple rss news - https://developer.apple.com/news/rss/news.rss) using a XMLParser object. The results of the parse the data in a tableView in UITableViewController. This tutorial is made with Xcode 10 and built for iOS 12.

Create New Project Xcode a new Single View App

XML parsing in iOS with Swift 4.0

Enter Project Name, Team name, Organization name, or identifier and select language swift.


Now design TableView, Cell in UITableViewController

TableView XML parse Data

1. First Create a XMLParser Class - //  XMLParser.swift
in struct declare properties of object


import Foundation
import UIKit

struct RSSItem {
    var title: String
    var description: String
    var pubDate: String
}

// download xml from a server
// parse xml to Foundation object
// call back


class FeedParser: NSObject, XMLParserDelegate {
    private var rssItem: [RSSItem] = []
    private var currentElement = ""
    
    private var currentTitle = ""
    {
        didSet{
            currentTitle = currentTitle.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        }
    }
    private var currentDescription = "" {
        didSet{
            currentDescription = currentDescription.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        }
    }
    
    private var currentPubDate = "" {
        didSet{
            currentPubDate = currentPubDate.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        }
    }
    private var parserCompletionHandeler: (([RSSItem])-> Void)?

// Download XML
    
   func parseFeed(url: String, completionHandler: (([RSSItem])-> Void)?){
        self.parserCompletionHandeler = completionHandler
        let request = URLRequest(url: URL(string: url)!)
        let urlSession = URLSession.shared
        let task = urlSession.dataTask(with: request) { (data, response, error) in
            guard let data = data else{
                if let error = error {
                    print(error.localizedDescription)
                }
                return
            }
            // parse our xml data
            
            let parser = XMLParser(data: data)
            parser.delegate = self
            parser.parse()
        }
        task.resume()
    }

    // XML Parser Delegate

    
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        currentElement = elementName
        
        if currentElement == "item"{
            currentTitle = ""
            currentDescription = ""
            currentPubDate = ""
        }
        
        
    }
    func parser(_ parser: XMLParser, foundCharacters string: String) {
        switch currentElement {
        case "title": currentTitle += string
            case "description": currentDescription += string
            case "pubDate": currentPubDate += string
        default: break
        }
    }
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        if elementName == "item" {
            let rssItem = RSSItem(title: currentTitle, description: currentDescription, pubDate: currentPubDate)
            self.rssItem.append(rssItem)
        }
    }
    func parserDidEndDocument(_ parser: XMLParser) {
        parserCompletionHandeler?(rssItem)
    }
    func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
        print(parseError.localizedDescription )
    }
}


2. Then Create TableView Cell Properties where are to display data. - NewsTableCell.swift

import Foundation
import UIKit

enum CellState {
    case expanded
    case collapsed
}

class NewsTableCell: UITableViewCell {
    
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var descriptionLabel: UILabel!{
        didSet{
            descriptionLabel.numberOfLines = 3
        }
    }
    
    @IBOutlet weak var dateLabel: UILabel!
    
    var item: RSSItem! {
        didSet {
            titleLabel.text = item.title
            descriptionLabel.text = item.description
            dateLabel.text = item.pubDate
            
            
        }
    }
}

3. Fatch Data UITableViewController TableView. // NewsTableViewController.swift

import Foundation
import UIKit

class NewsTableViewController: UITableViewController {
    private var rssItems: [RSSItem]?
    private var cellState: [CellState]?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.estimatedRowHeight = 155.0
        tableView.rowHeight = UITableView.automaticDimension
        fetchData()
    }
    private func fetchData(){
    let feedparser = FeedParser()
        feedparser.parseFeed(url: "https://developer.apple.com/news/rss/news.rss") { (rssItems) in
            self.rssItems = rssItems
            self.cellState = Array(repeating: .collapsed, count: rssItems.count)
            OperationQueue.main.addOperation {
                self.tableView.reloadSections(IndexSet(integer: 0), with: .left)
            }
            
        }
        
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let rssItems = rssItems else {
            return 0
        }
        return rssItems.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! NewsTableCell
        if let item = rssItems?[indexPath.row]{
            cell.item = item
            cell.selectionStyle = .none
            if let cellState = cellState{
                cell.descriptionLabel.numberOfLines = (cellState[indexPath.row] == .expanded) ? 0 : 4
            }
        }
        return cell
        
    }
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        let cell = tableView.cellForRow(at: indexPath) as! NewsTableCell
        tableView.beginUpdates()
        cell.descriptionLabel.numberOfLines = (cell.descriptionLabel.numberOfLines == 0) ? 3 : 0
        cellState?[indexPath.row] = (cell.descriptionLabel.numberOfLines == 0) ? .expanded: .collapsed
        tableView.endUpdates() 
    }
}

Finally Output - here parse data with XMLParser

Parse XML in iOS with Swift 4.0 with A SOAP Web Service Apple RSS News



Comments