swift3 reverse order for core data - uitableview

I am new of Swift 3. Here is my situation:
I saved some data in the core data. Like 1,2,3,4,5... I want to push them into the tableView with reversed order (5,4,3,2,1).
Here are some of my code:
Records:
override func viewWillAppear(_ animated: Bool) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "List")
do {
let result = try managedContext.fetch(request)
Array = result as! [NSManagedObject]
}
catch {
print("some error.....")
}
}
Push into cell
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
let item = Array[indexPath.row]
cell.textLabel?.text = item.value(forKey: "data") as? String
return cell
}
I tried something like
Array.reversed()
But the Xcode told me that the results are unused. Please help me. Thanks.

reversed is not mutating method, it will return object in reversed order so you need to use that return array.
array = array.reversed()
Note: It is better if property name start with lower case.

Related

How can I get an array to an NSManagedObject

I am sorry if I put out silly questions but I am new to Swift. I am building an app and so far it goes quite well. But now I want to delete some rows from my tableview which gets feeded from an Array with Strings. And then I want to save/fetch that using core data. I believe I have the code for it but the problem is that I am trying to save an array full of Strings. so I get error message saying: Cannot convert value of type 'String' to expected argument type 'NSManagedObject'. And therefore I am wondering, how can I solve this? Is there any way to "add those Strings to an NSManagedObject somehow?
Here are my code:
the array :
and here are the code:
import UIKit
import CoreData
class tableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (List.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
cell.textLabel?.text = List.self[indexPath.row]
cell.textLabel?.textColor = UIColor.white
cell.backgroundColor = UIColor.clear
return(cell)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
if editingStyle == .delete{
let rows = List[indexPath.row]
context.delete(rows)
(UIApplication.shared.delegate as! AppDelegate).saveContext()
do{
List = try context.fetch(MealsMenu.fetchRequest()) as! [String]
}
catch{
print(error)
}
}
myTableView.reloadData()
}
#IBOutlet weak var myTableView: UITableView!
override func viewDidAppear(_ animated: Bool) {
myTableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
CoredataClass.saveItems()
CoredataClass.loadData()
}
}
You will need to create a function like this
Imagine that your Entity is Recipe which has an string attribute recipeName which contains the name of the recipe.
func fetchPersistentData() -> [String] {
var recipes = [String]()
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return recipes
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<Recipe>(entityName: "Recipe")
do {
let fetchedResults = try managedContext.fetch(fetchRequest)
if fetchedResults.count > 0 {
recipes = fetchedResults.map { ("\($0.recipeName)")}
return recipes
}
} catch let error as NSError {
// Wrong handling
print(error.description)
}
return recipes
}

Insert new row on top of table view with CoreData

I want to make an app using CoreData.
I made the table view and add view controller to add data into Core Data and the table view to retrieve data and everything worked normal. But when I insert a new row from add view controller to the table view, it is going to the bottom of table view. I want to make it insert on top of the table view. I tried different code from the Internet but none worked with my code.
This is Table View Controller:
var List: [NSManagedObject] = []
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
// Configure Table View...
tableView.separatorColor = .clear
}
override func viewDidAppear(_ animated: Bool) {
let application: AppDelegate = UIApplication.shared.delegate as! AppDelegate
let context = application.persistentContainer.viewContext
let get = NSFetchRequest<NSManagedObject>(entityName: "Entity")
List = try! context.fetch(get)
tableView.reloadData()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return List.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainCell", for: indexPath) as! MainTableViewCell
let data: NSManagedObject = List[indexPath.row]
cell.objectName.text = data.value(forKey: "objectName") as? String
cell.objectPlace.text = data.value(forKey: "placeName") as? String
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 180
}
By default core data objects are fetched in the order they are inserted. To show the last added objects at first just reverse the fetched array.
override func viewDidAppear(_ animated: Bool) {
guard let application = UIApplication.shared.delegate as? AppDelegate else {
return
}
let context = application.persistentContainer.viewContext
let get = NSFetchRequest<NSManagedObject>(entityName: "Entity")
do {
List = try context.fetch(get).reversed()
tableView.reloadData()
} catch let error as NSError {
print(error.userInfo)
}
}
Inside the "NSFetchedResultsController" there is a sortDescriptor
let sortDescriptor = NSSortDescriptor(key: "dateSort", ascending: false)
Create an "entity". When adding to the context, I fill in the date. "Date()"

iOS How to send cell data to another VC use parse Swift

How i can send data from my table view cell, to another VC when in tap on cell.
My code for fetch data from DB:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! cellRequestsTVC
let good = data[indexPath.row]
name = good["username"] as! String
cell.userNameLable.text = "#\(name)"
area = good["place"] as! String
cell.areaLable.text = "\(area)"
cell.descriptionLable.text = good["description"] as? String
cell.priorityLable.text = "Priority " + ((good["priority"] as? Int)?.description)!
let imageProblems = good["image"] as? PFFile
imageProblems?.getDataInBackground{ (imageData, error)in
if imageData != nil {
let image = UIImage(data: imageData!)
cell.problemImage.image = image
}
}
return cell
}
It's working perfect. But now my target open data from cell in another VC.
Example:
Example
You have to implement UITableViewDelegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let good = data[indexPath.row]
// Here you can either perform a segue or push view controller to UINavigationController
//Push View controller
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc : DetailViewController = storyBoard.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
vc.sharedData = data // here you pass data
self.navigationController?.pushViewController(vc, animated: true)
}
In DetailViewController create object of data with required type
var sharedData : [String : Any]! // Take optional variable if object can be nil & here assuming data contains object of type [String : Any]
You can look the documentation here
UITableViewDelegate

Swift 4: UITableViewCell does will not display data upon initial load, but will load on second load

I have ran into a very interesting problem in my application. Upon viewing the users profile page the data in my tableview is being pulled and printed into the console, the problem though is that my information will not load into my tablecell.
If i were to leave the current tab and then go back to the profile page my data will then be loaded. I am using firebase in order to pull my information down.
I would like for the data to be there upon the first time viewing the page.
ProfileViewController
var cellId = "cell"
var userGames = [Game]()
var userCurrentGames = [Any]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(ProfileGameCell.self, forCellReuseIdentifier: cellId)
//I CALL MY FUNCTIONS UPON FIRST LOAD
getCurrentUser()
getUsersGames()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//I CALL FUCTIONS EVERY TIME THE VIEW LOADS INCASE DATA CHANGES
getCurrentUser()
getUsersInformation()
getUsersGames()
}
func getUsersGames() {
let ref = Database.database().reference()
let current = getCurrentUser()
//I FIND ALL THE GAMES IN THE USERS REF AND APPEND THEIR KEY TO THE ARRAY
ref.child("users").child(current).child("user games").observe(.value, with: {(snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
self.userCurrentGames = []
for snap in snapshot {
let gameKey = snap.key
print("SNAPSHOT DATAAA: \(gameKey)")
self.userCurrentGames.append(gameKey)
}
}
})
displayUsersGames()
}
func displayUsersGames() {
let ref = Database.database().reference()
self.userGames = []
//I FIND ALL THE GAMES AND APPEND THEM TO THE ACTUAL GAME ARRAY
for i in userCurrentGames {
ref.child("games").child("\(i)").observeSingleEvent(of: .value, with: { (gameSnap) in
if let gameDict = gameSnap.value as? Dictionary<String, AnyObject> {
let key = gameSnap.key
let game = Game(postKey: key, gameData: gameDict)
self.userGames.append(game)
self.tableView.reloadData()
}
})
}
}
Table View Functions
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let game = userGames[indexPath.row]
if let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as? ProfileGameCell {
cell.adminButton.tag = indexPath.row
cell.configureUserGameCell(game: game)
return cell
} else {
return ProfileGameCell()
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userGames.count
}
The problem is very clear:
observe works asynchronously – the result is returned later – so userCurrentGames is empty when displayUsersGames() is called.
A solution is to move displayUsersGames() into the completion block
...
ref.child("users").child(current).child("user games").observe(.value, with: {(snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
self.userCurrentGames = []
for snap in snapshot {
let gameKey = snap.key
print("SNAPSHOT DATAAA: \(gameKey)")
self.userCurrentGames.append(gameKey)
}
self.displayUsersGames()
}
})
Note:
Force downcast the cell
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! ProfileGameCell
The code must not crash. If it does it reveals a design error.

How to display dynamically data from Server in CollectionViewCell in TableViewCell with swift3?

I got my json link data from TableViewCell , and then retrieve that data from server and display in collectionView with related TableViewCell data.
How to display this data in swift3? Please, help me.
I got url link (mainThemeList.main_associated_url,main_name) from TableViewCell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let mainThemeList = mainHomeThemeTable[(indexPath as NSIndexPath).row]
let cell = tableView.dequeueReusableCell(withIdentifier: "homecell") as! HomeCategoryRowCell
DispatchQueue.main.async {
cell.categoryTitle.text = mainThemeList.main_name
cell.mainAssociatedURL.text = mainThemeList.main_associated_url
self.prefs.set(mainThemeList.main_name, forKey: "main_name")
cell.categoryTitle.font = UIFont.boldSystemFont(ofSize: 17.0)
cell.collectionView.reloadData()
}
DispatchQueue.main.async {
self.retrieveDataFromServer(associated_url: mainThemeList.main_associated_url,main_name: mainThemeList.main_name)
}
return cell
}
And then data related url link data from Server.
private func retrieveDataFromServe(associated_url : String , main_name: String) {
SwiftLoading().showLoading()
if Reachability().isInternetAvailable() == true {
self.rest.auth(auth: prefs.value(forKey: "access_token") as! String!)
rest.get(url: StringResource().mainURL + associated_url , parma: [ "show_min": "true" ], finished: {(result : NSDictionary, status : Int) -> Void in
self.assetsTable.removeAll()
if(status == 200){
let data = result["data"] as! NSArray
if (data.count>0){
for item in 0...(data.count) - 1 {
let themes : AnyObject = data[item] as AnyObject
let created = themes["created"] as! String
let assets_id = themes["id"] as! Int
let name = themes["name"] as! String
var poster_img_url = themes["poster_image_url"] as! String
let provider_id = themes["provider_id"] as! Int
poster_img_url = StringResource().posterURL + poster_img_url
self.assetsTable.append(AssetsTableItem(main_name: main_name,created: created,assets_id: assets_id, name: name, poster_image_url: poster_img_url,provider_id: provider_id))
}
}
SwiftLoading().hideLoading()
}else{
SwiftLoading().hideLoading()
}
})
}
}
Retrieve data from Server data store in assetsTable.
And then assetsTable data display in CollectionViewCell.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for: indexPath) as! HomeVideoCell
cell.movieTitle.text = list.name
cell.imageView.image = list.image
return cell
}
My problem is collectionViewCell data are duplicate with previous assetsTable data and didn't show correct data in CollectionView.
My tableViewCell show (Action, Drama) label and My CollectionViewCell show movies Name and Movie Image. I retrieve data for CollectionViewCell from server but CollectionViewCell didn't display related data.
in HomeVideoCell Subclass clean up data in prepareforreuse
override func prepareForReuse() {
super.prepareForReuse()
self.movieTitle.text = ""
self.imageView.image = nil
}

Resources