Reputation: 180
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
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
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
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