webview executing one of both urls - html

I'm doing a dictionary application. Some terms have animation, some don't. If ;
let url = URL(string: "http://bsstech.site/-Sozlukler/Fizik/(f.animasyonAdi ?? "").html")!
webview.load(URLRequest(url: url))
or let url = URL(string: "http://bsstech.site/-Sozlukler/Fizik/logo.html")!
webview.load(URLRequest(url: url)) I want to run.
Did I write the code as below, but I did not get the result I wanted.
if let f = fizik {
if (f.animasyonAdi != nil) {
let url = URL(string: "http://bsstech.site/-Sozlukler/Fizik/\(f.animasyonAdi ?? "").html")!
webview.load(URLRequest(url: url))
}else {
let url = URL(string: "http://bsstech.site/-Sozlukler/Fizik/logo.html")!
webview.load(URLRequest(url: url))
}
navigationItem.title = f.baslik
aciklama.text = f.aciklama
}
}
I would be very glad if you help.

Step 1: Create a WebViewViewController
Step 2: Added WebKitView, top title label, a cross button and activity IndicatorView in the WebViewVC.xib file, then insert outlets in the WebViewVC.swift
Step 3: Implement logic in the WebViewVC.swift like the following:
import UIKit
import WebKit
class WebViewVC: UIViewController {
// MARK: - Outlets
#IBOutlet private weak var webView: WKWebView!
#IBOutlet private weak var activityIndicatorView: UIActivityIndicatorView!
#IBOutlet private weak var titleLabel: UILabel!
// MARK: - Variables
private let userAgentValue = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16"
var navTitle: String?
var urlString: String?
// MARK: - View Cycle
override func viewDidLoad() {
super.viewDidLoad()
initView()
setupWebView()
loadData()
}
// MARK: - Event
#IBAction private func actionTapToCloseButton(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
// MARK: - Setting up View Controller
extension WebViewVC {
private func initView() {
titleLabel.text = navTitle
}
private func setupWebView() {
webView.navigationDelegate = self
webView.customUserAgent = userAgentValue
webView.isMultipleTouchEnabled = true
webView.isUserInteractionEnabled = true
}
private func loadData() {
if let `urlString` = urlString, !urlString.isEmpty, let query = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed), let url = URL(string: query) {
let request = URLRequest(url: url)
webView.load(request)
}
}
}
// MARK: - WKNavigationDelegate
extension WebViewVC: WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
activityIndicatorView.startAnimating()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
activityIndicatorView.stopAnimating()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
ShowPopUps.showDefaultAlert(title: "", message: "\(error.localizedDescription)", negativeActionText: "Ok")
activityIndicatorView.stopAnimating()
}
}
Step 4: Just Call
if let f = fizik {
var urlString: String? = nil
if (f.animasyonAdi != nil) {
urlString = http://bsstech.site/-Sozlukler/Fizik/\(f.animasyonAdi ?? "").html"
} else {
urlString = "http://bsstech.site/-Sozlukler/Fizik/logo.html"
}
let vc = WebViewVC()
vc.urlString = urlString
vc.navTitle = f.baslik
present(vc, animated: true, completion: nil)
}

Related

Passing data from StructA to VCA, and then from VCA to VCB

i hope im not breaking any rules, I've got a problem when im trying to pass data from struct to A and from A to B, now the problem happens when im trying to pass the data from B to C. it all works fine when i use delegates from A to B.
before i post my code, i would mention few things:
I parse JSON and use delegate to pass the data from A(is my struct) to B
I would like to send data from VCAA to VCB.
Here's my code:
my struct:
import Foundation
import UIKit
// MARK: - Struct Protocol
protocol QuizBrainDelegate {
func didUpdateQuestionsArray(questionsArr: [Questions])
func didUpdateMessage(message: String)
}
// MARK: -
struct QuizBrain {
let urlString = "https://5fa952f1c9b4e90016e6a5be.mockapi.io/data"
var delegate: QuizBrainDelegate?
// MARK: API Request.
func performRequest() {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, respone, error) in
if error != nil {
print("There's an error \(error!)")
}
if let safeData = data {
self.parseJSON(with: safeData)
}
}
task.resume()
}
}
/// parsing JSON method to parse the JSON
/// - Parameter data: The data returned by the server
func parseJSON(with data: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(Root.self, from: data)
let questionsArr = decodedData.data.questions // an array of questions
let thankUMessage = decodedData.data.thank_you_message
//passing the quiz arr to our Quiz's VC:
self.delegate?.didUpdateQuestionsArray(questionsArr: questionsArr)
self.delegate?.didUpdateMessage(message: thankUMessage)
} catch {
print("There was a problem with parsing JSON \(error)")
}
}
// MARK: - Struct Methods:
/// This func gets the next question everytime we answer the question
/// - Parameters:
/// - questionNum: a counter of the current question number.
/// - numOfQuestions: a counter of total amount of questions.
/// - Returns: returns the new value of questionNum which is the counter of our question number.
func nextQuestion(questionNum: Int, numOfQuestions: Int) -> Int {
return questionNum + 1
}
/// Func sets the score of the player
/// - Parameter scoreNum: the total score number.
/// - Returns: returns the score with 5 points once the user answers right
func getNumOfCurretQuestion(scoreNum: Int) ->Int {
return scoreNum+1
}
}
my VCA:
import UIKit
import Foundation
protocol QuizVCDelegate {
func changeTitle(_ message: String?)
func updateUserOptions(_ optionsArr: [String])
}
class QuizViewController: UIViewController, QuizBrainDelegate {
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var answerOption1: UIButton!
#IBOutlet weak var answerOption2: UIButton!
#IBOutlet weak var answerOption3: UIButton!
#IBOutlet weak var answerOption4: UIButton!
#IBOutlet weak var currQuestionLabel: UILabel!
var currentQuestionCounter = 0 // user's current number.
var numOfQuestion = 0 // counter of total questions.
var numOfOptions = 0 // counter of total options for each question
var quizBrain = QuizBrain() // an instance of struct QuizBrain for following MVC.
var messageToDisplay = ""
var quizArr = [Questions]() // array of Q and A
var storedAnswers = [String]() // an array of stored answers of the user
var delegate: QuizVCDelegate?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
quizBrain.performRequest() // Calling the URLRequest.
}
override func viewDidLoad() {
super.viewDidLoad()
quizBrain.delegate = self
}
#IBAction func answerButtonPressed(_ sender: UIButton) {
guard let userAnswer = sender.currentTitle else { return }
storedAnswers.append(userAnswer) // Storing the User's answers.
delegate?.updateUserOptions(storedAnswers)
delegate?.changeTitle(self.messageToDisplay)
sender.pulsate() // lets the user knows that he answered the question.
numOfQuestion = quizBrain.nextQuestion(questionNum: numOfQuestion, numOfQuestions: quizArr.count)
if numOfQuestion == quizArr.count { // checking if its equal to the total of questions in the array.
switchScreen()
}
//to make smooth transitaions im using a timer to update the UI:
if numOfQuestion < quizArr.count {
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
}
}
// a func that updates all the UI
#objc func updateUI() {
questionLabel.fadeTransition(0.4) // fade animation to our questionLabel
self.questionLabel.text = quizArr[numOfQuestion].question
while numOfOptions < quizArr[numOfQuestion].options.count {
switch numOfOptions { // 2-4 Options.
case 0: // none
self.answerOption1.setTitle(self.quizArr[numOfQuestion].options[numOfOptions].value, for: .normal) // Updates option1
case 1: // Joe
self.answerOption2.setTitle(self.quizArr[numOfQuestion].options[numOfOptions].value, for: .normal) // Updates option2
case 2: // Trump
self.answerOption3.setTitle(self.quizArr[numOfQuestion].options[numOfOptions].value, for: .normal) // Updates option3
case 3:
print("There's a case 4")
default:
print("There's a problem with Options Switch Statement")
}
numOfOptions+=1
}
numOfOptions = 0
currQuestionLabel.fadeTransition(0.4) // fade animation to our currentQuestion
currQuestionLabel.text = "Total: \(currentQuestionCounter)/\(numOfQuestion)" // updates the score.
}
/// func to update the arr with the JSON decoded questions and answers.
/// - Parameter questionsArr: an array of question objects.
func didUpdateQuestionsArray(questionsArr: [Questions]) {
DispatchQueue.main.async {
self.quizArr = questionsArr
self.updateUI()
}
}
func didUpdateMessage(message: String) {
DispatchQueue.main.async {
self.messageToDisplay = message
print(self.messageToDisplay)
}
}
// a func which presents our Thank you VC.
func switchScreen() {
let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
if let viewController = mainStoryboard.instantiateViewController(withIdentifier: "sbThanks") as? UIViewController {
viewController.modalPresentationStyle = .fullScreen
viewController.modalTransitionStyle = .crossDissolve
self.present(viewController, animated: true, completion: nil)
}
}
}
my VCB:
import Foundation
import UIKit
class ThanksViewController: UIViewController, QuizVCDelegate {
func updateUserOptions(_ optionsArr: [String]) {
DispatchQueue.main.async {
self.choosenAnswers = optionsArr
}
}
func changeTitle(_ message: String?) {
DispatchQueue.main.async {
self.titleLabel.text = message
}
}
var titleLabel = UILabel()
let bodyLabel = UILabel()
var choosenAnswers = [String]()
var quizVC = QuizViewController()
fileprivate func setupLabels() {
titleLabel.lineBreakMode = .byClipping // avoiding the 3 dots.
titleLabel.font = UIFont(name: "Futura", size: 20)
titleLabel.textColor = UIColor.black
titleLabel.textAlignment = .center
bodyLabel.text = "Your Answers:\n\(choosenAnswers)"
bodyLabel.numberOfLines = 0
bodyLabel.textColor = UIColor.black
bodyLabel.textAlignment = .center
}
fileprivate func setupStackView() {
let stackView = UIStackView(arrangedSubviews: [titleLabel, bodyLabel])
stackView.axis = .vertical
stackView.spacing = 8
view.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
stackView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -100).isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
quizVC.delegate = self
setupLabels()
setupStackView()
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTapAnimations)))
}
#objc fileprivate func handleTapAnimations() {
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseOut) {
self.titleLabel.transform = CGAffineTransform(translationX: -30, y: 0)
} completion: { (_) in
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.titleLabel.alpha = 0
self.titleLabel.transform = self.titleLabel.transform.translatedBy(x: 0, y: -100)
})
}
UIView.animate(withDuration: 0.5, delay: 0.5, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseOut) {
self.bodyLabel.transform = CGAffineTransform(translationX: -30, y: 0)
} completion: { (_) in
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.bodyLabel.alpha = 0
self.bodyLabel.transform = self.bodyLabel.transform.translatedBy(x: 0, y: -100)
})
}
}
}

Open pdf in tableview from a json file

I am in a bind.
My regular developer has secured a full time gig, and I am trying to finish a project.
Literally stuck on the last line of code.....
I have a tableview that parses a json file to populate and open a pdf file when a row is selected.
I reworked the tableview in order to add a searchbar and associated code, which works when running the bundle.
I am, however, stuck with connecting the didSelectRow with the appropriate pdf file.
Can someone please lend a hand? Thanks
import UIKit
import WebKit
// Model
struct Section {
var section: String
var pdfs: [PDF]
}
struct PDF {
var code: String
var name: String
var airport: String
}
class PdfVC: UIViewController {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var webView: WKWebView!
#IBOutlet weak var tableViewLeft: NSLayoutConstraint!
#IBOutlet weak var btnMenuLeft: NSLayoutConstraint!
#IBOutlet weak var btnMenu: UIButton!
#IBOutlet weak var searchBar: UISearchBar!
//json
var jsonData: [Section] = []
var filtedJsonData: [Section] = []
//WebView
var fileName: String?
var isVideo: Bool = false
var btnMenuClose:UIBarButtonItem?
override func viewDidLoad() {
super.viewDidLoad()
hideKeyboardWhenTappedAround()
// Setup TableView
tableView.delegate = self
tableView.dataSource = self
setupData()
tableView.reloadData()
// Setup SearchBar
searchBar.delegate = self
// Setup WebView
if let fileName = fileName {
isVideo = fileName.contains(".mp4")
if let range = fileName.range(of: isVideo ? ".mp4" : ".pdf") {
self.fileName!.removeSubrange(range)
}
}
if let file = Bundle.main.url(forResource: fileName ?? "", withExtension: isVideo ? ".mp4" : ".pdf", subdirectory: nil, localization: nil) {
let request = URLRequest(url: file)
webView.load(request)
}
if let image = UIImage(named: "ico_close") {
navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(onWebTap))
//self.navigationItem.leftItemsSupplementBackButton = true
btnMenuClose = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(onWebTap))
self.navigationItem.rightBarButtonItems = [btnMenuClose!];
}
//navigationItem.title = "Airport Maps"
}
private func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc private func dismissKeyboard() {
view.endEditing(true)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)
// title color to white
let titleTextAttributed: [NSAttributedString.Key: Any] = [.foregroundColor: UIColor.white, .font: UIFont(name: "HelveticaNeue-Light", size: 20) as Any]
self.navigationController?.navigationBar.titleTextAttributes = titleTextAttributed
// back arrow white
self.navigationController?.navigationBar.tintColor = UIColor.white
// blueish navigation bar
self.navigationController?.navigationBar.barTintColor = UIColor(red: 0.00, green: 0.54, blue: 0.92, alpha: 1.00)
self.navigationController?.navigationBar.isTranslucent = false
showMenu(false, animated: false)
}
private func setupData() {
// Parse data from local json file
if let path = Bundle.main.path(forResource: "airports", ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
if let jsonResult = jsonResult as? [Dictionary<String, String>] {
for result in jsonResult {
if !jsonData.contains(where: { $0.section == result["Section"] }) {
let section = Section(section: result["Section"] ?? "", pdfs: [])
jsonData.append(section)
}
let pdf = PDF(code: result["Code"] ?? "", name: result["Filename"] ?? "", airport: result["Name"] ?? "")
let index = jsonData.firstIndex(where: { $0.section == result["Section"] })
if let index = index {
jsonData[index].pdfs.append(pdf)
}
}
}
} catch {
// Handle error
print("error parsing json")
}
}
// Sort data before use
jsonData.sort(by: { $0.section < $1.section })
for index in 0..<jsonData.count {
jsonData[index].pdfs.sort(by: { $0.airport < $1.airport } )
}
filtedJsonData = jsonData
}
#objc func onWebTap() {
var left:CGFloat = 0
if tableViewLeft.constant == 0 {
left = -320
}
tableViewLeft.constant = left
showMenu(left != 0, animated: true)
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
func showMenu(_ show:Bool, animated:Bool) {
if let image = UIImage(named: show ? "ico_open" : "ico_close") {
btnMenuClose?.image = image
//navigationItem.rightBarButtonItem?.image = image
//}
//var left:CGFloat = 20
//if show == false {
// left = -64
}
//btnMenuLeft.constant = left
UIView.animate(withDuration: animated ? 0.3 : 0.0, delay: 0, options: .curveEaseInOut, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
}
// TableView
extension PdfVC: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return filtedJsonData.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if filtedJsonData[section].pdfs.count == 0 {
return nil
}
return filtedJsonData[section].section
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filtedJsonData[section].pdfs.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PdfCell", for: indexPath) as! PdfCell
let pdf = filtedJsonData[indexPath.section].pdfs[indexPath.row]
cell.setupCell(pdf: pdf)
return cell
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
dismissKeyboard()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let pdf = filtedJsonData[indexPath.section].pdfs[indexPath.row]
//THIS IS WHERE I'M STUCK<<<<<<<<<
self.title = pdf.airport
}
}
// SearchBar
extension PdfVC: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
for (index, data) in jsonData.enumerated() {
// Filter pdfs by code and name
let filtedPdf = data.pdfs.filter { $0.code.lowercased().prefix(searchText.count) == searchText.lowercased() || $0.airport.lowercased().prefix(searchText.count) == searchText.lowercased() }
filtedJsonData[index].pdfs = filtedPdf
}
tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.text = ""
tableView.reloadData()
}
}
Got it figured out. Thanks for all who spent some time reading my issue. I changed as follows
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let pdf = filtedJsonData[indexPath.section].pdfs[indexPath.row]
self.fileName = pdf.name
self.title = pdf.airport
DispatchQueue.main.async {
self.reloadWebView()
}
}
and added
private func reloadWebView() {
// Setup WebView
if let fileName = fileName {
isVideo = fileName.contains(".mp4")
if let range = fileName.range(of: isVideo ? ".mp4" : ".pdf") {
self.fileName!.removeSubrange(range)
}
}
if let file = Bundle.main.url(forResource: fileName ?? "", withExtension: isVideo ? ".mp4" : ".pdf", subdirectory: nil, localization: nil) {
let request = URLRequest(url: file)
webView.load(request)
}
}

Loading Thumbnails with YouTube Data API

I'm using the YouTube API and Alamofire to show videos for my YouTube channel. I'm having an issue that the thumbnails for the videos are messing up when scrolling. Like this:
I used Apple videos for the example. For some reason, the colors got messed up when creating the GIF, though. But you get the idea. Here are my relevant view controllers
TableViewController
import UIKit
class VideosTableViewController: UITableViewController, VideoModelDelegate {
var videos: [Video] = [Video]()
var selectedVideo:Video?
let model:VideoModel = VideoModel()
override func viewDidLoad() {
super.viewDidLoad()
if tableView.rowHeight == 250 {
tableView.estimatedRowHeight = 250
} else {
tableView.estimatedRowHeight = 96
}
tableView.rowHeight = UITableViewAutomaticDimension
model.getFeedVideo()
self.model.delegate = self
dataReady()
//
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func handleRefresh() {
dataReady()
refreshControl?.endRefreshing()
}
func dataReady() {
print("dataReady()")
self.videos = self.model.videoArray
self.tableView.reloadData()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return videos.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Configure the cell...
if indexPath.row == 0 {
var cell : NewVideoTableViewCell! = tableView.dequeueReusableCell(withIdentifier: "New Cell") as! NewVideoTableViewCell
cell.titleLabel.text = videos[indexPath.row].videoTitle
cell.thumbnail.clipsToBounds = true
cell.thumbnail.layer.cornerRadius = 5
let videoThumbnailURLString = videos[indexPath.row].videoThumbnailUrl
let videoThumbnailUrl = NSURL(string: videoThumbnailURLString)
if videoThumbnailUrl != nil {
let request = NSURLRequest(url: videoThumbnailUrl! as URL)
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) in
DispatchQueue.main.async {
cell.thumbnail.image = UIImage(data: data!)
}
})
dataTask.resume()
}
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let videoTitle = videos[indexPath.row].videoTitle
let title = cell.viewWithTag(2) as! UILabel
title.text = videoTitle
let videoThumbnailURLString = videos[indexPath.row].videoThumbnailUrl
let videoThumbnailUrl = NSURL(string: videoThumbnailURLString)
let imageView = cell.viewWithTag(1) as! UIImageView
if videoThumbnailUrl != nil {
let request = NSURLRequest(url: videoThumbnailUrl! as URL)
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) in
let imageView = cell.viewWithTag(1) as! UIImageView
DispatchQueue.main.async {
imageView.image = UIImage(data: data!)
}
})
imageView.clipsToBounds = true
imageView.layer.cornerRadius = 3
imageView.layer.borderColor = UIColor.lightGray.cgColor
imageView.layer.borderWidth = 0.1
dataTask.resume()
}
return cell
}
}
}
VideoModel
import UIKit
import Alamofire
protocol VideoModelDelegate {
func dataReady()
}
let API_KEY = "My API Key"
let UPLOADS_PLAYLIST_ID = "My Playlist"
let CHANNEL_ID = "My Channel ID"
let parameters = ["part":"snippet","maxResults":50,"channelId":CHANNEL_ID,"playlistId":UPLOADS_PLAYLIST_ID,"key":API_KEY] as [String : Any]
class VideoModel: NSObject {
var videoArray = [Video]()
var delegate: VideoModelDelegate?
func getFeedVideo() {
Alamofire.request("https://www.googleapis.com/youtube/v3/playlistItems", parameters: parameters, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
if let JSON = response.result.value {
if let dictionary = JSON as? [String: Any] {
var arrayOfVideos = [Video]()
guard let items = dictionary["items"] as? NSArray else { return }
for items in dictionary["items"] as! NSArray {
print(items)
// Create video objects off of the JSON response
let videoObj = Video()
videoObj.videoID = (items as AnyObject).value(forKeyPath: "snippet.resourceId.videoId") as! String
videoObj.videoTitle = (items as AnyObject).value(forKeyPath: "snippet.title") as! String
videoObj.videoDescription = (items as AnyObject).value(forKeyPath: "snippet.description") as! String
videoObj.videoThumbnailUrl = (items as AnyObject).value(forKeyPath: "snippet.thumbnails.maxres.url") as! String
arrayOfVideos.append(videoObj)
}
self.videoArray = arrayOfVideos
if self.delegate != nil {
self.delegate!.dataReady()
}
}
}
}
}
Video
import UIKit
class Video: NSObject {
var videoID:String = ""
var videoTitle:String = ""
var videoDescription:String = ""
var videoThumbnailUrl:String = ""
}
So, do you see how the thumbnails get are jumpy? Any ideas? Thanks for the help!

How to place JSON data in a NScollectionview

I am grabbing data from a url which is a PHP script that is JSON encoding my data from a MySQL database. My data is coming into my app and I know how to parse it but I am unsure how to place my data inside of each item's textField.stringvalue in my Collection View. Most of the information I have found on this subject is all for iOS and I am making an app for OS X.
ViewController.swift
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var collectionView: NSCollectionView!
var productCategories: [ProductCategory]?
let baseURL = "http://myURL"
override func viewDidLoad() {
super.viewDidLoad()
getJSON()
self.collectionView.reloadData()
}
func getJSON(){
let url = NSURL(string: baseURL)
let request = NSURLRequest(url: url! as URL)
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: request as URLRequest) { (data,response,error) -> Void in
if error == nil {
let swiftyJSON = JSON(data:data!)
print(swiftyJSON)
let product = swiftyJSON[].arrayValue
for name in product{
let names = name["product_name"].stringValue
print(names)
}
} else{
print("Error")
}
}
task.resume()
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
extension ViewController: NSCollectionViewDataSource{
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = productCategories?.count {
return count
}
return 0
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let item = collectionView.makeItem(withIdentifier: "ImageCollectionViewItem", for: indexPath)
item.textField?.stringValue = Product.product_name
return item
}
}
Model.swift
import Foundation
class ProductCategory: NSObject {
var name: String?
var productss: [Product]?
var type: String?
}
class Product: NSObject {
var id: NSNumber?
var product_name: String?
var product_price: NSNumber?
var product_description: String?
var product_image: String?
var product_download: String?
var product_video: String?
var product_featured: Int?
}

How do I use json instead of plist to populate TableView

I have a working App which takes data from a pList on a remote server. However, I now want to use json instead of plist and am struggling with understanding how to do this! Any help much appreciated and any examples awesome.
Some selected code - first download of plist and second populating the TableView using the downloaded plist. Note: I have not included ALL the code.
#IBAction func startDownload(sender: AnyObject) {
progressView.hidden = false
let url = NSURL(string: "http://ftp.iphoneData#dittodata.host-ed.me/Annotations/myAnnotationsKalkan.plist")!
downloadTask = backgroundSession.downloadTaskWithURL(url)
downloadTask.resume()
}
func showFileWithPath(path: String){
let isFileFound:Bool? = NSFileManager.defaultManager().fileExistsAtPath(path)
if isFileFound == true{
let viewer = UIDocumentInteractionController(URL: NSURL(fileURLWithPath: path))
viewer.delegate = self
viewer.presentPreviewAnimated(true)
// print("file is found")
}
}
#IBOutlet var progressView: UIProgressView!
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 1
func URLSession(session: NSURLSession,
downloadTask: NSURLSessionDownloadTask,
didFinishDownloadingToURL location: NSURL){
let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let documentDirectoryPath:String = path[0]
let fileManager = NSFileManager()
let destinationURLForFile = NSURL(fileURLWithPath: documentDirectoryPath.stringByAppendingString("/myAnnotationsKalkan.plist.plist"))
if fileManager.fileExistsAtPath(destinationURLForFile.path!){
showFileWithPath(destinationURLForFile.path!)
}
else{
do {
try fileManager.moveItemAtURL(location, toURL: destinationURLForFile)
// show file
showFileWithPath(destinationURLForFile.path!)
}catch{
print("An error occurred while moving file to destination url")
}
}
}
// 2
func URLSession(session: NSURLSession,
downloadTask: NSURLSessionDownloadTask,
didWriteData bytesWritten: Int64,
totalBytesWritten: Int64,
totalBytesExpectedToWrite: Int64){
progressView.setProgress(Float(totalBytesWritten)/Float(totalBytesExpectedToWrite), animated: true)
}
func URLSession(session: NSURLSession,
task: NSURLSessionTask,
didCompleteWithError error: NSError?){
downloadTask = nil
progressView.setProgress(0.0, animated: true)
if (error != nil) {
print(error?.description)
}else{
// print("The task finished transferring data successfully")
progressView.hidden = true
}
}
// TableViewController.swift
/ museumTemplate
//
import UIKit
class MyTableViewController: UITableViewController {
var titleData = [String]()
var subTitleData = [String]()
var stateData = [String]()
var codeData = [String]()
var infoData = [String]()
var openData = [String]()
var phoneData = [String]()
var emailData = [String]()
var webData = [String]()
var latData = [Double]()
var lonData = [Double]()
var titleToPass = [String]()
var thisState = [String]()
var stateOrAlpha = ""
var titleText = ""
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = titleText
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
let sourcePath = documentsPath.stringByAppendingPathComponent("myAnnotationsKalkan.plist.plist")
if let content = NSArray(contentsOfFile: sourcePath as String){
let descriptor = NSSortDescriptor(key: stateOrAlpha, ascending: true)
let myMuseum = content.sortedArrayUsingDescriptors([descriptor])
for item in myMuseum{
titleData.append(item.objectForKey("title") as! String)
subTitleData.append(item.objectForKey("subtitle") as! String)
infoData.append(item.objectForKey("info") as! String)
phoneData.append(item.objectForKey("phone") as! String)
webData.append(item.objectForKey("web") as! String)
emailData.append(item.objectForKey("email") as! String)
latData.append(item.objectForKey("latitude") as! Double)
lonData.append(item.objectForKey("longitude") as! Double)
}
}
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return titleData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) as UITableViewCell
// Configure the cell..title and subTitle.
cell.textLabel!.text = titleData[indexPath.row]
return cell
}
i use Alamofire wich is more easier and safe to do Web requests, but here is a code without it:
let urlPath = "YourUrlRequest"
let session = NSURLSession.sharedSession()
let url = NSURL(string: urlPath)!
session.dataTaskWithURL(url) {( data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if let responseData = data {
do {
let jsonObject = try NSJSONSerialization.JSONObjectWithData(responseData, options: []) as! NSArray
for dataDict : AnyObject in jsonObject {
let idj: String = dataDict.objectForKey("id") as!String
let namej: String = dataDict.objectForKey("name") as! String
let indicativej: String = dataDict.objectForKey("indicative") as! String
let flagj: String = dataDict.objectForKey("flag") as! String
saveCountryFromWeb(idj, name: namej, indicative: indicativej, flag: flagj)
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
}
}.resume()
Hope the helps, tell me in case you want a sample with alamofire which i recommend ;)
func retrieveBarcodeData(){
let databaseref = FIRDatabase.database().reference()
databaseref.child("barcodes").queryOrderedByKey().observeEventType(.ChildAdded, withBlock: {
snapshot in
let codig = snapshot.value!["codigo"] as! String
let desc = snapshot.value!["designacao"] as! String
let Url = snapshot.value!["ImageURL"] as! String
barcodes.insert(BarCodeStruct(code: codig, description: desc, ImageURL: Url),atIndex: 0)
self.tableView.reloadData()
})
}
Don't forget to configure your database in firebase, and install firebase with cocoapods and put FIRApp.configure() in your appDelegate didFinishLaunchingWithOptions
I tried this code for downloading a simple json file from a server and it seems to work:
override func viewDidLoad() {
super.viewDidLoad()
let requestURL: NSURL = NSURL(string: "http://ftp.iphoneData#dittodata.host-ed.me/Annotations/testData4.json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("File downloaded.")
// print(testData4.json)
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
if let users = json["users"] as? [[String: AnyObject]] {
for user in users {
if let name = user["name"] as? String {
if let subtitle = user["subtitle"] as? String {
print(name,subtitle)
}
}
}
}
}catch {
print("Error with Json: \(error)")
}
}
}
task.resume()
}