Conversion Swift2 -> Swift3: Errors with Any - swift3

I'm using CustomCollectionViewLayout from https://github.com/brightec/CustomCollectionViewLayout.
After the conversion from Swift2 to Swift3 two errors regarding Any occurs.
Error1:
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return self.itemAttributes[indexPath.section][indexPath.row] as! UICollectionViewLayoutAttributes
}
Message error:
CustomCollectionViewLayout.swift:115:54: Type 'Any' has no subscript members
Error 2:
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attributes = [UICollectionViewLayoutAttributes]()
if self.itemAttributes != nil {
for section in self.itemAttributes {
let filteredArray = (section as AnyObject).filtered(
using: NSPredicate(block: { (evaluatedObject, bindings) -> Bool in
return rect.intersects(evaluatedObject.frame)
})
) as! [UICollectionViewLayoutAttributes]
attributes.append(contentsOf: filteredArray)
}
}
return attributes
}
Message Error:
Value of type 'Any?' has no member 'frame'
Any ideas how to fix the Problems with Any/AnyObject?

I solved the errors, replace your both the methods to below ones
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
//return self.itemAttributes[indexPath.section][indexPath.row] as! UICollectionViewLayoutAttributes
let arr = self.itemAttributes[indexPath.section] as! NSMutableArray
return arr[indexPath.row] as! UICollectionViewLayoutAttributes
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attributes = [UICollectionViewLayoutAttributes]()
if self.itemAttributes != nil {
for section in self.itemAttributes {
let filteredArray = (section as! NSMutableArray).filtered(
using: NSPredicate(block: { (evaluatedObject , bindings) -> Bool in
let a = evaluatedObject as! UICollectionViewLayoutAttributes
return rect.intersects(a.frame)
})
) as! [UICollectionViewLayoutAttributes]
attributes.append(contentsOf: filteredArray)
}
}
return attributes
}

Related

I Found Error of Could Not Cast Value of Type when i load my json in Tableview

This is my code , could not append array type to UIImage , api is successfully loaded , i have problem in appending data
var images = UIImage
func downloadJsonWithURL() {
let url = NSURL(string: urlString)
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSObject {
print(jsonObj!.value(forKey: "guid"))
if let actorArray = jsonObj!.value(forKey: "guid") as? [NSObject] {
if let actorDict = actorArray as? NSObject
{
if let name = actorDict.value(forKey: "rendered") {
**self.images.append(name as! UIImage)**
print("\(name)")
}
}
}
OperationQueue.main.addOperation({
self.tableView.reloadData()
})
}
}).resume()
}
this is my rest api
guid {1}
rendered : http://thenewschef.com/wp-content/uploads/2018/02/startup.jpeg
So, You Can Do This
var images = [[String:AnyObject]]()
override func viewDidLoad() {
super.viewDidLoad()
downloadJsonWithURL()
}
//Tableview methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return images.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 135
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DemoTableCell", for: indexPath) as! DemoTableCell
let dict = images[indexPath.row]
URLSession.shared.dataTask(with: NSURL(string: dict["rendered"] as! String)! as URL, completionHandler: { (data, response, error) -> Void in
if error != nil {
print(error as Any)
return
}
DispatchQueue.main.async(execute: { () -> Void in
let image = UIImage(data: data!)
cell.imgView?.image = image
})
}).resume()
return cell
}
//your api call
func downloadJsonWithURL() {
let urlString = "https://thenewschef.com/wp-json/wp/v2/media"
let url = NSURL(string: urlString)
print(url as Any)
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) {
print((jsonObj as AnyObject).value(forKey: "guid") as Any)
let responseJSON = (jsonObj as AnyObject).value(forKey: "guid") as Any
let json = (responseJSON as AnyObject) as? NSArray
self.images = json as! [[String:AnyObject]]
print(self.images)
OperationQueue.main.addOperation({
self.demoTable.reloadData()
})
}
}).resume()
}
That's it you got your UIImage.
Enhanced implementation of above solution using Higher order function to avoid all the cast dance.
Use the below code to fetch the response form Server & filter the required imageUrl's in a single array.
func downloadJsonWithURL() {
let urlString = "https://thenewschef.com/wp-json/wp/v2/media"
let url = NSURL(string: urlString)
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {[weak self] (data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) {
let guids = (jsonObj as? [[String: Any]])?.map { $0["guid"] }
let imagesArray = (guids as? [[String: Any]])?.map {$0["rendered"]} as? [String]
OperationQueue.main.addOperation({
//Reload Table here...
})
}
}).resume()
}

How to display array of images on Collection View in Swift

func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("gallery count : \(self.arrayGallerySingle.count)")
return self.arrayGallerySingle.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gallerycell", for: indexPath) as! GalleryViewCell
return cell
}
//API Fetching method
func galleryFetch(){
let prs = [
"id": dealIDGallery,
"deal_single_page": "1" as String
]
Service.StartWithoutLoading(prs as [String : AnyObject]?, onCompletion: { result in
let jsonResponseSingle = result as? NSDictionary
print(" jsonResponse\(String(describing: jsonResponseSingle))")
if let resultGallery = jsonResponseSingle?.value(forKey: "result") as? NSArray{
for keyValuesGallery in resultGallery {
let gallerySingle = (keyValuesGallery as AnyObject).value(forKey: "gallery_images") as? NSArray
print("Gallery Images Key: \(gallerySingle)")
self.arrayGallerySingle = gallerySingle as! [AnyObject]
DispatchQueue.main.async { () -> Void in
self.collectionView?.reloadData()
}
}
}
})
}
How will I show an array of images with key gallery_images on UICollectionViewCell?This line print("Gallery Images Key: \(gallerySingle)") prints the required array of images on console but I am unable to show on collectionView. My JSON response is http://www.jsoneditoronline.org/?id=8eccb63976d76be7d0b2d1b0e8f02306. I am using SDWebImage in my project also.I already checked datasource connection & collectionView IBoutlet as well as an image inside the cell. I am a beginner in Swift pls help and if required any further information pls ask
Swift 3.0 This is my updated Answer hope it will also help someone
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("gallery count : \(self.arrayGallerySingle.count)")
return self.arrayGallerySingle.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gallerycell", for: indexPath) as! GalleryViewCell
if let imgUrl = arrayGallerySingle[indexPath.row] as? String {
if let url = NSURL(string: imgUrl) {
cell.galleryImage?.sd_setImage(with: url as URL, placeholderImage: UIImage(named: "place holder image"), options: .lowPriority)
}
else{
let alertController = UIAlertController(title: "No Gallery Images", message: "test", preferredStyle: .alert)
let okButton = UIAlertAction(title: "Okay", style: .default, handler: nil)
alertController.addAction(okButton)
alertController.present(alertController, animated: true, completion: nil)
}
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: collectionView.frame.size.width/2, height: collectionView.frame.size.height/3)
}
func galleryFetch(){
let prs = [
"id": dealIDGallery,
"deal_single_page": "1" as String
]
Service.StartWithoutLoading(prs as [String : AnyObject]?, onCompletion: { result in
let jsonResponseSingle = result as? NSDictionary
print(" jsonResponse\(String(describing: jsonResponseSingle))")
if let resultGallery = jsonResponseSingle?.value(forKey: "result") as? NSArray{
for keyValuesGallery in resultGallery {
let gallerySingle = (keyValuesGallery as AnyObject).value(forKey: "gallery_images") as? NSArray
print("Gallery Images Key: \(gallerySingle)")
self.arrayGallerySingle = gallerySingle as! [AnyObject]
if self.arrayGallerySingle.count > 0 {
DispatchQueue.main.async { () -> Void in
self.collectionView?.reloadData()
}
} else {
let alertController = UIAlertController(title: "Message", message: "No images found.", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: self.doSomething))
self.present(alertController, animated: true, completion: nil)
}
}
}
})
}
Swift 3.0
you can implement this way with SDWebcache to load image in collectionView cell image.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gallerycell", for: indexPath) as! GalleryViewCell
if let imgUrl = arrayGallerySingle[indexPath.row] as? String {
if let url = URL(string: imgUrl) {
//Replace with your imageView outlet
cell.imageView.sd_setImageWithURL(url, placeholderImage: UIImage(named: "place holder image"), options: .lowPriority)
}
}
return cell
}
And If you want to display 6 cell in collectionView Then you have to set UICollectionViewLayout method to defined size of cell as below.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: collectionView.frame.size.width/2, height: collectionView.frame.size.height/3)
}
You can display alert when array count is not empty and why you reload Collection view inside for loop, Implement it like below.
Service.StartWithoutLoading(prs as [String : AnyObject]?, onCompletion: { result in
let jsonResponseSingle = result as? NSDictionary
print(" jsonResponse\(String(describing: jsonResponseSingle))")
if let resultGallery = jsonResponseSingle?.value(forKey: "result") as? NSArray{
for keyValuesGallery in resultGallery {
let gallerySingle = (keyValuesGallery as AnyObject).value(forKey: "gallery_images") as? NSArray
print("Gallery Images Key: \(gallerySingle)")
self.arrayGallerySingle = gallerySingle as! [AnyObject]
}
if self.arrayGallerySingle.count > 0 {
DispatchQueue.main.async { () -> Void in
self.collectionView?.reloadData()
}
} else {
let alertController = UIAlertController(title: "Your Title", message: "their is no images", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alertController, animated: tru, completion: nil)
}
}
})

Swift 3.1 Label in TableViewCell - unexpectedly found nil

I'm trying to create two tableViews in one UIViewController. But when I'm trying to assign value to UILabel, getting an error: fatal error: unexpectedly found nil while unwrapping an Optional value
I wonder why, I have almost the same code for TableViewController with one tableView and it works with no issues. It looks like these UI Labels are not initialized when trying to assign value to it. But don't understand how to fix it.
It fails here:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell?
if tableView == self.guestsTableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "guestCell", for: indexPath) as! GuestAtTableTableViewCell
if let guestsTable = guestsTableFetchedResultsController?.object(at: indexPath) {
print(guestsTable.guestName) // works fine, prints the value
print(cell.guestNameLabel.text) //fails here with error fatal error: unexpectedly found nil while unwrapping an Optional value
cell.guestNameLabel.text = guestsTable.guestName
cell.openTimeLabel.text = String(describing: guestsTable.openTime)
cell.cellDelegate = self
}
}
else if tableView == self.ordersTableView {
cell = tableView.dequeueReusableCell(withIdentifier: "orderCell", for: indexPath)
//to be done
}
// Configure the cell...
return cell!
}
Full code of this class:
import UIKit
import CoreData
class TableUIViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CellWithButtonDelegate {
//The following two variables will not be nil because prepare for segue will set them
var tableName: String?
var table: TablesTable? = nil
fileprivate var currentTableSession: TableSessionTable? {
get {
let tableSessionTable = TableSessionTable()
return tableSessionTable.getCurrentTableSession(table: table!)
}
}
fileprivate var guestsTableFetchedResultsController: NSFetchedResultsController<GuestsTable>?
fileprivate var ordersTableFetchedResultsController: NSFetchedResultsController<OrdersTable>?
#IBOutlet weak var tableNameLabel: UILabel!
#IBOutlet weak var tableCapacityLabel: UILabel!
#IBOutlet weak var tableCountOfGuestsLabel: UILabel!
#IBOutlet weak var tableDescriptionTextView: UITextView!
#IBAction func closeTableButtonPressed(_ sender: UIButton) {
}
#IBOutlet weak var guestsTableView: UITableView!
#IBOutlet weak var ordersTableView: UITableView!
#IBAction func addGuestButtonPressed(_ sender: UIButton) {
let guestsTable = GuestsTable()
let tablesTable = TablesTable()
let table = Table(tableName: tableName!, tableCapacity: 0, locationX: nil, locationY: nil, tableImage: nil)
try? guestsTable.addNewGuest(table: tablesTable.getOrCreateTable(table: table))
updateUI()
}
#IBAction func addOrderButtonPressed(_ sender: UIButton) {
}
override func viewDidLoad() {
guestsTableView.dataSource = self
guestsTableView.delegate = self
guestsTableView.register(GuestAtTableTableViewCell.self, forCellReuseIdentifier: "guestCell")
ordersTableView.dataSource = self
ordersTableView.delegate = self
ordersTableView.register(UITableViewCell.self, forCellReuseIdentifier: "orderCell")
updateUI()
}
func didPressButton(table: TablesTable) {
}
private func updateUI () {
let tableView = guestsTableView
let context = AppDelegate.viewContext
let request : NSFetchRequest<GuestsTable> = GuestsTable.fetchRequest()
request.predicate = NSPredicate(format: "table= %#", currentTableSession!)
request.sortDescriptors = [NSSortDescriptor(key: "guestName", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))]
guestsTableFetchedResultsController = NSFetchedResultsController<GuestsTable>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
try? guestsTableFetchedResultsController?.performFetch()
tableView?.reloadData()
}
private func updateUI1 () {
let tableView = ordersTableView
let context = AppDelegate.viewContext
let request : NSFetchRequest<OrdersTable> = OrdersTable.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "menuItem", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))]
ordersTableFetchedResultsController = NSFetchedResultsController<OrdersTable>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
try? ordersTableFetchedResultsController?.performFetch()
tableView?.reloadData()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell?
if tableView == self.guestsTableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "guestCell", for: indexPath) as! GuestAtTableTableViewCell
if let guestsTable = guestsTableFetchedResultsController?.object(at: indexPath) {
print(guestsTable.guestName) // works fine, prints the value
print(cell.guestNameLabel.text) //fails here with error fatal error: unexpectedly found nil while unwrapping an Optional value
cell.guestNameLabel.text = guestsTable.guestName
cell.openTimeLabel.text = String(describing: guestsTable.openTime)
cell.cellDelegate = self
}
}
else if tableView == self.ordersTableView {
cell = tableView.dequeueReusableCell(withIdentifier: "orderCell", for: indexPath)
//to be done
}
// Configure the cell...
return cell!
}
func numberOfSections(in tableView: UITableView) -> Int {
if tableView == self.guestsTableView {
return guestsTableFetchedResultsController?.sections?.count ?? 1
}
else if tableView == self.ordersTableView {
return ordersTableFetchedResultsController?.sections?.count ?? 1
}
else {return 1}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.guestsTableView {
if let sections = guestsTableFetchedResultsController?.sections, sections.count > 0 {
return sections[section].numberOfObjects
}
else {
return 0
}
}
else if tableView == self.ordersTableView {
if let sections = ordersTableFetchedResultsController?.sections, sections.count > 0 {
return sections[section].numberOfObjects
}
else {
return 0
}
}
else {return 0}
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if tableView == self.guestsTableView {
if let sections = guestsTableFetchedResultsController?.sections, sections.count > 0 {
return sections[section].name
}
else {
return nil
}
}
else if tableView == self.ordersTableView {
if let sections = ordersTableFetchedResultsController?.sections, sections.count > 0 {
return sections[section].name
}
else {
return nil
}
}
else {return nil}
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
if tableView == guestsTableView {
return guestsTableFetchedResultsController?.sectionIndexTitles
}
else {
return ordersTableFetchedResultsController?.sectionIndexTitles
}
}
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
if tableView == guestsTableView {
return guestsTableFetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
}
else if tableView == ordersTableView {
return ordersTableFetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
}
else {return 0}
}
}
And full code of UITableViewCell class:
import UIKit
class GuestAtTableTableViewCell: UITableViewCell {
weak var cellDelegate: CellWithButtonDelegate?
#IBOutlet weak var guestNameLabel: UILabel!
#IBOutlet weak var openTimeLabel: UILabel!
#IBAction func didPressButton(_ sender: UIButton) {
}
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
}
}
I guess you have a xib for your UITableViewCell register the xib instead of the class.
Use the following:
guestsTableView.register(UINib.init(nibName: "GuestAtTableTableViewCell", bundle: nil), forCellReuseIdentifier: "guestCell")
As you have created a prototype cell in the storyboard itself you should select the cell in the storyboard and set its identifier there. Next remove the register line from your code for guestCell. It should work

Nil Error While Running

i am working on TODO app,it was all completed and was running well but suddenly it begins to give an error "fatal error: unexpectedly found nil while unwrapping an Optional value".Need Some Guide!
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet weak var tableView: UITableView!
var tasks : [Task] = [ ]
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
getdata()
tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tasks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let task = tasks[indexPath.row]
if task.isimportant{
cell.textLabel?.text = " ★ \(task.name!)"
}else{
cell.textLabel?.text = task.name!
}
return cell
}
func getdata() {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
do{
tasks = try context.fetch(Task.fetchRequest())
}
catch {
print ("Failed!")
}
}
}
You should always avoid unwrapping optionals with an ! because of the danger of encountering a runtime error if the optional is missing. Try the following:
let taskName = task.name ?? "No name"
if task.isimportant{
cell.textLabel?.text = " ★ \(taskName)"
}else{
cell.textLabel?.text = taskName
}

Type 'Any' has no subscript members AND Value of type 'Any' has no member 'Count'

I am receiving the following two Errors below when creating an array of Strings in Swift 3.0 on Xcode8:
Value of type 'Any' has no member 'count'
Original Code: return todoData.count
"Fixed" with: return (todoData as AnyObject).count
Type 'Any' has no subscript members
Original Code: if let text = todoData[indexPath.row] {
See full code below:
let todoData = UserDefaults.standard.value(forKey: "todosArray")
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let todoData = todoData {
return todoData.count //Error 1.
} else {
return 0
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TableViewCell
if let todoData = todoData {
if let text = todoData[indexPath.row] { //Error 2.
cell.label.text = text as? String
}
}
return cell
}
Your issue
is here:
let todoData = UserDefaults.standard.value(forKey: "todosArray")
The compiler has inferred the type of todoDatato be Any?, because that line calls UserDefaults override of the NSObject method value(forKey:), which returns Any?. You can see for yourself by option-clicking the variable. The type Any? doesn't have a property count, or a subscript that takes an Int.
The naive solution is to just cast it:
let todoData = UserDefaults.standard.value(forKey: "todosArray") as? [ToDo]
But a better option is to replace value(forKey:) with a call to array(forKey:), which will do the cast for you:
let todoData = UserDefaults.standard.array(forKey: "todosArray")
As a side note...
this code:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let todoData = todoData {
return todoData.count //Error 1.
} else {
return 0
}
}
can be expressed much more simply as:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return todoData.count ?? 0
}
This uses the null coalescing operator (??). You can find out more about that, here.
And this code:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TableViewCell
if let todoData = todoData {
if let text = todoData[indexPath.row] { //Error 2.
cell.label.text = text as? String
}
}
return cell
}
can be rewritten as:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TableViewCell
cell.label.text = todoData?[indexPath.row] as? String
return cell
}
This uses subscripting with optional chaining. You can read more about that, here.
Modify your answer to this
let todoData = UserDefaults.standard.value(forKey: "todosArray")
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let todoData = todoData as? [String] {
return todoData.count
} else {
return 0
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TableViewCell
if let todoData = todoData as? [String] {
if let text = todoData[indexPath.row] {
cell.label.text = text
}
}
return cell
}