Im my Swift app, I need to display data in a tableview. The data at server side changes often, and therefore I need to delete any previous data and add the new data fetched. I am able to delete and fetch and I can see the new data in the console as well as realm browser. However, the data is not available in the table view controller from Results.
class ServiceProvidersTableViewController: UITableViewController {
// MARK: - Data Source
var serviceSubCategory: String = ""
var serviceSubCategories: Results<ServiceSubCategory>?
// MARK: - Realm
let realm = try! Realm()
let fetchData = FetchData()
override func viewDidLoad() {
super.viewDidLoad()
self.deleteSubCategories()
FetchData.get(ServiceSubCategory.self, params: ["subCategoryId": serviceSubCategory], success: {
self.infoAlert("Service Categories", message: "Fetch Successful")
}) {
self.infoAlert("Failed", message: "Fetch Failed")
}
self.fetchSubCategories()
}
func deleteSubCategories()
{
let subCategories = realm.objects(ServiceSubCategory.self)
print("Before delete \(subCategories)")
try! realm.write{
realm.delete(subCategories)
}
print("After delete \(subCategories)")
}
func fetchSubCategories() {
self.realm.refresh()
self.serviceSubCategories = self.realm.objects(ServiceSubCategory)
tableView.reloadData()
print("After fetch \(self.serviceSubCategories)")
}
struct Storyboard {
static let CellIndentifier = "ServiceProvidersCell"
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(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
print(self.serviceSubCategories!.count)
return self.serviceSubCategories!.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(Storyboard.CellIndentifier, forIndexPath: indexPath) as! ServiceProvidersTableViewCell
print(serviceSubCategories)
cell.serviceSubCategories = self.serviceSubCategories![indexPath.row]
return cell
}
func infoAlert(title:String,message:String) -> Void {
let actionSheetController: UIAlertController = UIAlertController(title:title, message:message, preferredStyle: .Alert)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in }
actionSheetController.addAction(cancelAction)
self.presentViewController(actionSheetController, animated: true, completion: nil)
}
}
My guess is that you need to delete the object from the local "serviceSubCategory" and not just from the server.
Put a tableView.reloadData() everytime the server listener fires.
Probably in the fetchSubCategories() and deleteSubCategories() functions.
I solved (I should say, I am dumb) as follows:-
The FetchData method has a callback success, which in the example I used displays an alert.
I created another function in the tableViewController and called this in the success call back. Inside the new method I called self.tableView.reloadData().
Thanks to all for helping me out
Related
Sorry, I'm a noob,
I am a bit stuck. I have been researching this for awhile and cannot find anything to help.
So, my problems is:
I have a Table View controller with a bunch of Cells (Depending on users contact address book). These Cells contain the users contacts information (Name and #) users can select up to 3 cells (Contacts).
That all works fine, I just need to know how to get the name and # labels data from each cell so I can display that information in another View Controller (CAContactsList) when I press the "Done" button (which I'm also stumped with).
My Current Table View Controller Class:
class AddContactsListTableView: UITableViewController {
var contacts = [FetchedContact]()
override func viewDidLoad() {
super.viewDidLoad()
fetchContacts()
}
private func fetchContacts() {
print("Attempting to fetch contacts")
let store = CNContactStore()
store.requestAccess(for: .contacts) { (granted, error) in
if let error = error {
print("failed to request access", error)
return
}
if granted {
print("access granted")
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
do {
try store.enumerateContacts(with: request, usingBlock: { (contact, stopPointer) in
print(contact.givenName)
self.contacts.append(FetchedContact(firstName: contact.givenName, lastName: contact.familyName, telephone: contact.phoneNumbers.first?.value.stringValue ?? ""))
})
} catch let error {
print("Failed to enumerate contact", error)
}
} else {
print("access denied")
}
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// return the number of rows
return contacts.count
}
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
//Max Number of contacts allowed to be selected
let limit = 3
if let selectedRows = tableView.indexPathsForSelectedRows {
if selectedRows.count == limit {
let alertController = UIAlertController(title: "Oops", message: "Sorry, but you are limited to only \(limit) Contacts", preferredStyle: UIAlertController.Style.alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: {action in}))
self.present(alertController, animated: true, completion: nil)
return nil
}
}
return indexPath
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "AddContactsCell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? AddContactsCell
// Configure the cell...
cell?.NamesLabel.text = contacts[indexPath.row].firstName + " " + contacts[indexPath.row].lastName
cell?.NumberLabel.text = contacts[indexPath.row].telephone
return cell!
}
}
My Current Cell Class:
class AddContactsCell: UITableViewCell {
//Mark Properties
#IBOutlet weak var NamesLabel: UILabel!
#IBOutlet weak var NumberLabel: UILabel!
#IBOutlet weak var ButtonSelector: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// update UI with Checkmark when Selected
accessoryType = selected ? .checkmark : .none
}
}
And my Fetched Contacts Class
struct FetchedContact {
var firstName: String
var lastName: String
var telephone: String
}
Any help would be Greatly Appreciated!
Override the prepare(for segue: UIStoryboardSegue, sender: Any?) in the AddContactsListTableView class where you can pass the selected contacts to the next view controller.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Pass the selected object to the new view controller.
if let selectedRows = tableView.indexPathsForSelectedRows {
let selectedContacts = selectedRows.map{contacts[$0.row]}
let newVC = segue.destination as! NewViewController
newVC.contacts = selectedContacts
}
}
See this tutorial for more.
So basically you are already on the right track querying the table view's indexPathsForSelectedRows since it will contain the indices you need to filter your contacts for. The selected contacts should be:
guard let selectedIndices = tableView.indexPathsForSelectedRows else { return }
let selectedContacts = selectedIndices.map { contacts[$0.item] }
[Edit]: Use a more concise version
I need to show info about movies(taken from https://developers.themoviedb.org/) in tableView. I'm doing network request using a singleton and then pass parsed data to tableViewController through completion handler. I can print received data but I can't properly set them in tableView cell. Could you please help me how to fix this problem.
Network Manager
func getMovies(completion: #escaping ([Movies]?) -> Void) {
guard let url = URL(string: "https://api.themoviedb.org/3/movie/now_playing?api_key=\(apiKey)&language=en")
else { fatalError("Wrong URL") }
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let jsonData = data {
let decoder = JSONDecoder()
do {
let moviesResult = try decoder.decode(MoviesResult.self, from: jsonData)
let movies = moviesResult.results
completion(movies)
}
catch {
print(error)
}
}
}.resume()
}
Movies View Controller
var movies = [Movies]()
override func viewDidLoad() {
super.viewDidLoad()
network.getMovies { result in
if let result = result {
self.movies = result
print(self.movies)
}
}
extension MoviesViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return movies.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let movie = movies[indexPath.row]
print(movie)
if let cell = tableView.dequeueReusableCell(withIdentifier: "moviesMainInfo", for: indexPath) as? MovieTableViewCell {
cell.filmTitle.text = movie.title
cell.filmRating.text = String(movie.popularity!)
return cell
}
return UITableViewCell()
}
}
Parsed result: [MovieApp.Movies(genreIDs: Optional([14, 28, 12]), overview: Optional("Wonder Woman comes into conflict with the Soviet Union during the Cold War in the 1980s and finds a formidable foe by the name of the Cheetah."), popularity: Optional(1927.057), title: Optional("Wonder Woman 1984"), releaseDate: Optional("2020-12-16"), posterPath: Optional("/8UlWHLMpgZm9bx6QYh0NFoq67TZ.jpg")),
You are doing everything correctly, you just need to reload your UITableView when data arrives. Be aware that you need to reload your UITableView on the main thread, because UIKit isn't thread safe:
otherwise your application will most probably crash:
private func reloadTableView() {
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
Also I encourage you to extract your networking function from viewDidLoad. An other improvement is to use [weak self] in your closures to avoid memory leaks:
private func loadData() {
network.getMovies { [weak self] result in
if let result = result {
self?.movies = result
print(self?.movies)
self?.reloadTableView()
} else {
// Maybe show some info that the data could not be fetched
}
}
}
And in your viewDidLoad just call it:
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
I created a tableView with custom cells that each cell has an image.
In the model class, I created a func mainPulatesData() to use URLSession dataTask method to retrieve data from url, and convert data into UIImage in the completion handler block, then add image into an variable of array of UIImage.
The process of retrieve data and adding them into UIImage array was perform in DispatchQueue.global(qos: .userInitiated).async block. based on the print message, the images did be added into array.
however, even I created an instance of model class in tableView controller, and invokes the mainPulatesData() in viewDidlLoad, the image didn't show up in the table.
Based on other print message in table view controller class, I found even it can be added into array in model class, but it seems like doesn't work on the instance of model class in tableView controller.
that's the code in model class to gain image data:
func mainPulatesData() {
let session = URLSession.shared
if myURLs.count > 0{
print("\(myURLs.count) urls")
for url in myURLs{
let task = session.dataTask(with: url, completionHandler: { (data,response, error) in
let imageData = data
DispatchQueue.global(qos: .userInitiated).async {
if imageData != nil{
if let image = UIImage(data: imageData!){
self.imageList.append(image)
print("\(self.imageList.count) images added.")
}
}
else{
print("nil")
}
}
})
task.resume()
}
}
}
that's the code in view controller to create instance of model:
override func viewDidLoad() {
super.viewDidLoad()
myModel.mainPulatesURLs()
myModel.mainPulatesData()
loadImages()
}
private func loadImages(){
if myModel.imageList.count > 0{
tableView.reloadData()
}
else{
print("data nil")
}
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myModel.imageList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath) as! ImageTableViewCell
if myModel.imageList.count > 0{
let image = myModel.imageList[indexPath.row]
cell.tableImage = image
return cell
}
return cell
}
The reason is that the images or imageList isn't ready by the time cellForRowAt is called after you reloadData().
A good practice is to use placeholder images in the beginning and only load image when a table view cell is visible instead of everything at once. Something like:
// VC class
private var modelList = [MyModel(url: url1), MyModel(url: url2), ...]
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return modelList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath) as! ImageTableViewCell
cell.update(model: modelList[indexPath.row])
return cell
}
// Cell class
#IBOutlet weak var cellImageView: UIImageView!
func update(model: MyModel) {
model.fetchImage(callback: { image in
self.cellImageView.image = image
})
}
// Model class
final class MyModel: NSObject {
let url: URL
private var _imageCache: UIImage?
init(url: URL) {
self.url = url
}
func fetchImage(callback: #escaping (UIImage?) -> Void) {
if let img = self._imageCache {
callback(img)
return
}
let task = URLSession.shared.dataTask(with: self.url, completionHandler: { data, _, _ in
if let imageData = data, let img = UIImage(data: imageData) {
self._imageCache = img
callback(img)
} else {
callback(nil)
}
})
task.resume()
}
}
Images are not displayed because you download them in background thread (asynchronously), and loadImages() is called synchronously. That means loadImage() is called before myModel.mainPulatesData() is executed, so when your images are downloaded, tableview is not being updated (reloadData() is not called). You should create Protocol to notify UIViewController, that data has been downloaded, or use Completion Handler.
Simple example of handler I am using, I call this in my viewDidLoad, it requests data from server and return an array of [Reservation]?
ReservationTableModule.requestAllReservations { [weak self] reservations in
guard let `self` = self else {
return
}
guard let `reservations` = `reservations` else {
return
}
self.reservations = reservations
.reservationsTableView.reloadData()
}
this is actual request function
class func requestAllReservations(handler: #escaping ([Reservation]?) -> Void) {
let url = "reservations/all"
APIModel.shared.requestWithLocation(.post, URL: url, parameters: nil) { data in
let reservations = data?["reservations"].to(type: Reservation.self) as? [Reservation]
handler(reservations)
}
}
handler: #escaping ([Reservation]?) -> Void is called completion handler, you should, I guess make it handler: #escaping ([UIImage]?) -> Void and after your data downloaded call handler(reservations)
You should take note of the sequence of your function call here:
myModel.mainPulatesURLs() --> populates myURLs
myModel.mainPulatesData() --> populates image from myURLs in forloop asynchronously.
loadImages() --> called asynchronously.
while you're loading your images from myModel.mainPulatesData() you already called loadImages() which myModel.imageList was still empty.
you should call loadImages() after a callback from myModel.mainPulatesData() or when you're sure that the images where already loaded.
you can use dispatch_group_t to configure the callbacks.
here as requested:
import UIKit
var myURLs: [String] = ["urlA", "urlB", "urlC", "urlD"]
// we define the group for our asynchronous fetch. also works in synchronous config
var fetchGroup = DispatchGroup()
for urlString in myURLs {
// for every url fetch we define, we will call an 'enter' to issue that there is a new block for us to wait or monitor
fetchGroup.enter()
// the fetch goes here
let url = URL(string: urlString)!
URLSession.shared.downloadTask(with: URLRequest(url: url), completionHandler: { (urlReq, urlRes, error) in
// do your download config here...
// now that the block has downloaded the image, we are to notify that it is done by calling 'leave'
fetchGroup.leave()
}).resume()
}
// now this is where our config will be used.
fetchGroup.notify(queue: DispatchQueue.main) {
// reload your table here as all of the image were fetched regardless of download error.
}
I think my problem spans over multiple VC.
In the table VC I perform a fetch request that returns an array of Floor objects. This entity has 2 attributes (floor number and number of rooms in floors). If I assign 2 floors (0 and 1) it works and prints them. The next VC contains a picker that displays the number of floors and a text box that is used to assign the number of rooms per floor. There must be a problem with this function because it gets called only if the first item of the picker is selected (prints the result). If I have 2 floors (0 and 1 in the picker) and floor 1 is selected the function does not assign the room value to any other floor. It doesn't matter how many floors, the function will only work for the first one. I have looked of how to modify the function but did not find any suitable solutions.
The second problem is that the table view does only display one row. Lets say that for floor 0 I assign 1; than only a row with 1 appears. If anyone could help me it would mean a lot to me. Thank you
Please see the code below for the picker function:
#IBAction func setTheFloors(_ sender: UIButton) {
if storedFloors.count > 0 {
if storedFloors.first?.floorNumber == pickedFloor! {
storedFloors.first?.numberOfRooms = roomNumberValue
print("\(storedFloors.first?.floorNumber) + \(storedFloors.first?.numberOfRooms)")
}
}
do {
try managedObjectContext.save()
} catch {
fatalError("could not save context because: \(error)")
}
}
#IBAction func nextStep(_ sender: UIButton) {
}
private func loadFloorData() {
let floorRequest: NSFetchRequest<Floors> = Floors.fetchRequest()
do {
storedFloors = try managedObjectContext.fetch(floorRequest)
} catch {
print("could not load data from core \(error.localizedDescription)")
}
}
private func spinnerItems() {
for i in 0...floorValue! - 1 {
convertedFloorValues.append(String(i))
}
}
and this section of code is for the table view.
class RoomAndAlarmTypeTableVC: UITableViewController, NSFetchedResultsControllerDelegate {
//MARK: - Properties
private var managedObjectContext: NSManagedObjectContext!
private var storedFloors = [Floors]()
private var floorsAndRooms = [String: String]()
//MARK: - Actions
override func viewDidLoad() {
super.viewDidLoad()
managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
loadFloorData()
tableView.delegate = self
tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func loadFloorData() {
let floorRequest: NSFetchRequest<Floors> = Floors.fetchRequest()
do {
storedFloors = try managedObjectContext.fetch(floorRequest)
print("\(storedFloors)")
} catch {
print("could not load data from core \(error.localizedDescription)")
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return storedFloors.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let specificFloor = storedFloors[section]
return Int(specificFloor.numberOfRooms)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "house cell", for: indexPath) as! ViewRooomNumberCell
let tableSections = storedFloors[indexPath.section]
let floorItem = tableSections.numberOfRooms[indexPath.row]
let floorNumber = String(floorItem.numberOfRooms)
cell.floorNumberTxt.text = floorNumber
return cell
}
}
I am currently working on an app in which the user can save their favorite place to a table view and by selecting a row in that table view it opens a new view controller with a web view. In that web view, I want it to display a google search of the place that the user has added to the table.
I've tried using NSUserDefaults to try and save the URL of the google search but I was unable to access it from within a different view controller file.
I've researched on google but have still been unable to find exactly what I'm looking for.
I wanted to find out if anyone knows how to save a URL and access it from within a different file to be the URL that the web view displays.
Here's my code:
SecondViewController(Has a table view with the names of the places that the user saves, selecting should open a view with a google search of the name of the place that the user saved)
import UIKit
var favoritePlaces = [String]()
class SecondViewController: UIViewController, UITableViewDelegate, UITextFieldDelegate, UITableViewDataSource {
#IBAction func alertButtonPressed(sender: AnyObject) {
let addNewPlaceAlert = UIAlertController(title: "Add A Favorite Place", message: "Enter the name of the place here", preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Done", style: .Default) { (alert: UIAlertAction!) -> Void in
NSLog("You pressed button OK")
addNewPlaceAlert.dismissViewControllerAnimated(true, completion: nil)
let textField = addNewPlaceAlert.textFields![0] as UITextField
favoritePlaces.append(textField.text!)
self.favoritePlacesTable.reloadData()
NSUserDefaults.standardUserDefaults().setObject(favoritePlaces, forKey: "favoritePlaces")
}
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (alert: UIAlertAction!) -> Void in
NSLog("You pressed button OK")
}
addNewPlaceAlert.addAction(saveAction)
addNewPlaceAlert.addAction(cancelAction)
addNewPlaceAlert.addTextFieldWithConfigurationHandler { (textField: UITextField!) in
}
presentViewController(addNewPlaceAlert, animated: true, completion: nil)
}
func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
if buttonIndex == 1 {
favoritePlaces.append(alertView.textFieldAtIndex(0)!.text!)
favoritePlacesTable.reloadData()
}
}
#IBOutlet var favoritePlacesTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
if NSUserDefaults.standardUserDefaults().objectForKey("favoritePlaces") != nil {
favoritePlaces = NSUserDefaults.standardUserDefaults().objectForKey("favoritePlaces") as! [String]
}
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
favoritePlacesTable.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
print("Row: \(row)")
print(favoritePlaces[row] as String)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section:Int) -> Int {
return favoritePlaces.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell? = favoritePlacesTable.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell
cell!.textLabel?.text = favoritePlaces[indexPath.row]
if (cell != nil)
{
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle,
reuseIdentifier: "Cell")
}
// At this point, we definitely have a cell -- either dequeued or newly created,
// so let's force unwrap the optional into a UITableViewCell
return cell!
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
let row = indexPath.row
performSegueWithIdentifier("showContent", sender: row)
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
favoritePlaces.removeAtIndex(indexPath.row)
NSUserDefaults.standardUserDefaults().setObject(favoritePlaces, forKey: "favoritePlaces")
favoritePlacesTable.reloadData()
}
}
override func viewDidAppear(animated: Bool) {
favoritePlacesTable.reloadData()
}
}
Favorite Place View Controller(The view that opens once a user selects a row)
import UIKit
class FavoritePlaceViewController: UIViewController {
enter code here
#IBOutlet var favoritePlaceWV: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL(string: "https://www.google.com")!
favoritePlaceWV.loadRequest(NSURLRequest(URL: url))
// Do any additional setup after loading the view.
NSUserDefaults.standardUserDefaults().objectForKey("secondUrl")
}
`enter code here`override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I used a struct to define base urls for different end points as follows. This is accessible to all models and view controllers as well, according to my need. I guess this was your requirement.
struct URL {
private static let BaseURL = "https://yourdomain.com/urlendpoint/api/"
private static let CurrentVersion = "v202/json/en/"
private static let year15 = "2015/"
private static let currentYear = "2016/"
//MARK:- Update URl
static var UpdateURL: String {
return BaseURL + CurrentVersion + currentYear + "update.json"
}
static var FirstURL: [String] {
var urls: [String] = []
for i in 0...11 {
urls.append(BaseURL + CurrentVersion + currentYear + + FirstMonth + String(i) + ".json")
}
return urls
}
static var SecondURL: String {
return BaseURL + CurrentVersion + "second.json"
}
//MARK:- Dream
static var ThirdURL: String {
return BaseURL + CurrentVersion + "third_results.json"
}
static var FourthURL: String {
return BaseURL + CurrentVersion + "fourth.json"
}
static var FifthURL: String {
return BaseURL + CurrentVersion + currentYear + "fifth.json"
}
}