Aditya Hari Kishan
Aditya Hari Kishan

Reputation: 180

JSON Image Parsing IOS Swift 3.0

I'm totally new for iOS swift deveploment. I'm trying to do json image parsing with dynamic data/url, I tried without a result to search for examples for displaying data and images in table view or list view, can any one help me in achieving this task?

Here is the following link for image parsing

http://www.androidbegin.com/tutorial/jsonparsetutorial.txt

Upvotes: 1

Views: 1665

Answers (3)

Amul4608
Amul4608

Reputation: 1448

Swift 3.0 create new Xcode project take one table view create tableViewCell File create NSObject Class File take one lable(Country Name) take one imageView(flag) put Below Code in Right Place(note: place is mention before starting code)

ViewController Code

import UIKit

class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource {

    @IBOutlet var imgTable: UITableView!
    var ArrayData:[Datad] = []
    override func viewDidLoad() {
        super.viewDidLoad()
        service()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return ArrayData.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CellDemo") as! ImageTableViewCell
        let objarr = ArrayData[indexPath.row]
        cell.lblContry.text = objarr.Country
     cell.imgflag.setImageFrom(imageURLString: objarr.Countryflag, completionHandler: { (complete, image, error) in
        })
        return cell

    }
    func service()
    {
       let url = URL(string: "http://www.androidbegin.com/tutorial/jsonparsetutorial.txt")
        var urlRequest = URLRequest(url: url!, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 60)
        urlRequest.httpMethod = "GET"
        let session = URLSession.shared
        let task = session.dataTask(with: urlRequest) { (data, response, errorresponce) in

            if errorresponce != nil
            {
                print(errorresponce?.localizedDescription ?? "Value Not Found")
            }
            else
            {
                do
                {
                    if let dictionary = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
                    {
                        DispatchQueue.main.async {
                            for datacon in (dictionary.value(forKey: "worldpopulation") as! NSArray)                        {

                                let cellonr = Datad(dictionary: datacon as! NSDictionary )

                                self.ArrayData.append(cellonr)
                                self.imgTable.reloadData()

                            }

                        }

                                           }
                    else
                    {
                        print("value not found")
                    }

                }
                catch let error as Error!
                {
                    print(error.localizedDescription)
                }
            }
        }
        task.resume()
    }

}

TableView Cell Code

import UIKit

class ImageTableViewCell: UITableViewCell {

    @IBOutlet var lblContry: UILabel!
    @IBOutlet var imgflag: UIImageView!
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

NSObject File

import UIKit

class Datad: NSObject {

    var Country:String!
    var Countryflag:String!
    init(dictionary:NSDictionary)
    {
        Country =  (dictionary.value(forKey: "country") as! String)
        Countryflag =  (dictionary.value(forKey: "flag") as! String)

    }

}

copy this two file (Note below 2 File Name Not Change Strikly Follow ) first

ImageDownloadManager.swift

import Foundation
import UIKit

typealias DownloadHandler = (_ success: Bool,  _ image: UIImage?,  _ error: Error?) -> Void
typealias DownloadProgressHandler = (_ totalBytesExpected : Int64,  _ bytesDownloaded: Int64, _ error : Error?) -> Void

private var kImageURLKey : String = "imageURLKey"

extension UIImageView{

    var imageURLId : String{

        get{
            return objc_getAssociatedObject(self, &kImageURLKey) as! String
        }
        set(newValue){
            objc_setAssociatedObject(self, &kImageURLKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    func setImageFrom(imageURLString : String,
                      placeHolderImage: UIImage? = nil,
                      completionHandler: DownloadHandler?) {

        if (imageURLString.characters.count > 0){

            if ((placeHolderImage) != nil){
                self.image = placeHolderImage;
            }

            self.imageURLId = imageURLString

            ImageDownloadManager.sharedManager.getImageFromURL(imageURLString: imageURLString)
            { (success : Bool, image : UIImage?, error :Error?) in

                if (success){
                    self.isUserInteractionEnabled = true
                    self.updateImage(image: image!, imageUrl: imageURLString)
                }

                if ((completionHandler) != nil){
                    completionHandler!(success, image, error)
                }
            }
        }
    }

    func setImageFrom(imageURLString : String,
                      placeHolderImage: UIImage? = nil,
                      progressHandler: @escaping DownloadProgressHandler,
                      completionHandler: DownloadHandler?) {

        if (imageURLString.characters.count > 0){

            if ((placeHolderImage) != nil){
                self.image = placeHolderImage;
            }

            self.imageURLId = imageURLString


            ImageDownloadManager.sharedManager.getImageFromURL(imageURLString: imageURLString,
                                                               progessHandler: { (expectedBytes:Int64, downloadedBytes:Int64, error:Error?) in
                                                                if error != nil {
                                                                    completionHandler!(false, nil, error)
                                                                }else{
                                                                    progressHandler(expectedBytes, downloadedBytes, nil)
                                                                }


            },
                                                               completionHandler: {  (success:Bool, image:UIImage?, error:Error?) in

                                                                if (success){
                                                                    self.updateImage(image: image!, imageUrl: imageURLString)
                                                                }

                                                                if ((completionHandler) != nil){
                                                                    completionHandler!(success, image, error)
                                                                }
            })
        }

    }

    private func updateImage(image:UIImage, imageUrl:String) {

        if (imageUrl == imageURLId)
        {
            UIView.transition(with: self,
                              duration: 0.4,
                              options: .transitionCrossDissolve,
                              animations: {
                                self.image = image;
            },
                              completion: nil)
        }
    }
}

UIImageView+AsyncLoad.swift

import UIKit


struct ImageDownloadInfo {
    let downloadURLString : String
    let downloadTask : URLSessionTask
    let progressHandler : DownloadProgressHandler?
    let completionHandler : DownloadHandler?
}

class ImageDownloadManager: NSObject {

    static let sharedManager : ImageDownloadManager = ImageDownloadManager()

    var imageLoaderQueue : [String:ImageDownloadInfo] = [:]
    var imageCache : NSCache<NSString, UIImage> = NSCache()

    lazy var downloadsSession : URLSession = URLSession(configuration: URLSessionConfiguration.default)
    lazy var downloadDelegateSession : URLSession = URLSession(configuration: URLSessionConfiguration.default, delegate: sharedManager, delegateQueue: OperationQueue.main)

    func getImageFromURL(imageURLString:String,
                         completionHandler:@escaping DownloadHandler) {

        let cachedImage : UIImage? = imageCache.object(forKey: imageURLString as NSString)

        if cachedImage != nil {
            completionHandler(true, cachedImage, nil)
        }else {
            downloadImageFor(imageURLString: imageURLString, downloadHandler: completionHandler)
        }
    }

    func getImageFromURL(imageURLString:String,
                         progessHandler: @escaping DownloadProgressHandler,
                         completionHandler: @escaping DownloadHandler ){
        let cachedImage : UIImage? = imageCache.object(forKey: imageURLString as NSString)

        if cachedImage != nil {
            progessHandler(1, 1, nil)
            completionHandler(true, cachedImage, nil)
        }else {
            downloadImageFor(imageURLString: imageURLString, progressHandler: progessHandler, completionHandler:completionHandler)
        }
    }

    private func downloadImageFor(imageURLString:String,
                                  downloadHandler: @escaping DownloadHandler) {


        var imageDownloadInfo: ImageDownloadInfo? = imageLoaderQueue[imageURLString]

        if imageDownloadInfo == nil {

            let imageLoaderTask = downloadsSession.dataTask(with: URL(string: imageURLString)!, completionHandler: { (data : Data?, response : URLResponse?, error : Error?) in

                OperationQueue.main.addOperation({

                    if (error != nil){
                        downloadHandler(false, nil, error)
                    }
                    else{
                        let image = UIImage(data: data!)
                        if image != nil {
                            ImageDownloadManager.sharedManager.imageCache.setObject(image!, forKey: imageURLString as NSString)
                            downloadHandler(true, image, nil)
                        }
                        else {
                            downloadHandler(false, nil, error)
                        }
                    }
                    ImageDownloadManager.sharedManager.imageLoaderQueue[imageURLString] = nil
                })
            })

            imageDownloadInfo = ImageDownloadInfo(downloadURLString: imageURLString,
                                                  downloadTask: imageLoaderTask,
                                                  progressHandler: nil,
                                                  completionHandler:nil)

            imageLoaderQueue[imageURLString] = imageDownloadInfo
            imageDownloadInfo?.downloadTask.resume()
        }
    }

    private func downloadImageFor(imageURLString:String,
                                  progressHandler: @escaping DownloadProgressHandler,
                                  completionHandler: @escaping DownloadHandler) {

        var imageDownloadInfo: ImageDownloadInfo? = imageLoaderQueue[imageURLString]

        if imageDownloadInfo == nil {

            let imageLoaderTask = downloadDelegateSession.downloadTask(with: URL(string: imageURLString)!)

            imageDownloadInfo = ImageDownloadInfo(downloadURLString: imageURLString,
                                                  downloadTask: imageLoaderTask,
                                                  progressHandler: progressHandler,
                                                  completionHandler:completionHandler)

            imageLoaderQueue[imageURLString] = imageDownloadInfo
            imageDownloadInfo?.downloadTask.resume()
        }

    }
}

extension ImageDownloadManager : URLSessionDownloadDelegate {

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){

        let imageUrl : String = (downloadTask.originalRequest?.url?.absoluteString)!
        let imageDownloadInfo: ImageDownloadInfo? = imageLoaderQueue[imageUrl]

        if imageDownloadInfo != nil {


            do {
                let data = try Data(contentsOf: location)

                let image = UIImage(data: data)

                ImageDownloadManager.sharedManager.imageCache.setObject(image!, forKey: imageUrl as NSString)

                if let completionHandler = imageDownloadInfo?.completionHandler {

                    completionHandler(true, image, nil)
                }

            } catch {
                print(error.localizedDescription)
            }
        }
    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64){

        let imageUrl = downloadTask.originalRequest?.url?.absoluteString
        let imageDownloadInfo: ImageDownloadInfo? = imageLoaderQueue[imageUrl!]

        if imageDownloadInfo != nil {

            if let progressHandler = imageDownloadInfo?.progressHandler {
                progressHandler(totalBytesExpectedToWrite, totalBytesWritten, nil)
            }
        }
    }

}

Upvotes: 0

Mukesh
Mukesh

Reputation: 3690

As a newbie i think this Library will ease your most of the work,

the syntax is very dev friendly and simple , No struggling of if let syntax and nesting.Example usage create json with one simple line let json = JSON(data : data) and many more with custom data types.Have a look of this Lib

let rank = json["worldpopulation"][0]["rank"].int let country = json["worldpopulation"][0]["country"].string let flag = json["worldpopulation"][0]["flag"].string

Upvotes: 1

Dheeraj D
Dheeraj D

Reputation: 4451

    func countriesResponseReceived(response : NSDictionary)
    {
        let arrCountries = (response.object(forKey: "worldpopulation")) as! NSArray

        for dict in arrCountries!
        {
            let dictData = dict as! NSDictionary
            let rank = dictData.object(forKey: "rank") as! NSInteger
            let country = dictData.object(forKey: "country") as! String
            let flag = dictData.object(forKey: "flag") as! String
        }
    }

Upvotes: 0

Related Questions