[__NSOrderedSetM objectAtIndex:]: Index 10 beyond bounds [ 0 .. 9[ - ios

I changed my main data structure containing all of my JSON objects to be used in my table view from a NSMutableArray to a NSMutableOrderedSet. Now, my app loads the first ten objects from the API correctly but the second I want to scroll down, it crashes. Any suggestions ?
override func scrollViewDidScroll(scrollView: UIScrollView) {
if (scrollView.contentOffset.y + view.frame.size.height > scrollView.contentSize.height * 0.8) {
populateEditorials()
}
}
func populateEditorials() {
if populatingEditorials {
return
}
populatingEditorials = true
Alamofire.request(GWNetworking.Router.Editorials(self.currentPage)).responseJSON() { response in
if let JSON = response.result.value {
/*
if response.result.error == nil {
*/
/* Creating objects for every single editorial is long running work, so we put that work on a background queue, to keep the app very responsive. */
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
// Making an array of all the node IDs from the JSON file
var nodeIDArray : [Int]
/* var nodeCounter : Int = 0 */
if (JSON .isKindOfClass(NSDictionary)) {
for node in JSON as! Dictionary<String, AnyObject> {
var nodeIDValue = node.0
var lastItem : Int = 0
self.nodeIDArray.addObject(nodeIDValue)
if var editorialElement : EditorialElement = EditorialElement(title: "init", nodeID: 0, timeStamp: 0, imageURL: "init", author: "init", issueNumber: "init", volumeNumber: "init", articleContent: "init") {
editorialElement.title = node.1["title"] as! String
editorialElement.nodeID = Int(nodeIDValue)
let timeStampString = node.1["revision_timestamp"] as! String
editorialElement.timeStamp = Int(timeStampString)!
editorialElement.imageURL = String(node.1["image_url"])
editorialElement.author = String(node.1["author"])
editorialElement.issueNumber = String(node.1["issue_int"])
editorialElement.volumeNumber = String(node.1["volume_int"])
editorialElement.articleContent = String(node.1["html_content"])
lastItem = self.editorialObjects.count
self.editorialObjects.addObject(editorialElement)
/* Sorting the elements in order of newest to oldest (as the array index increases] */
self.editorialObjects.sort({ $0.timeStamp > $1.timeStamp })
let indexPaths = (lastItem..<self.editorialObjects.count).map { NSIndexPath(forItem: $0, inSection: 0) }
dispatch_async(dispatch_get_main_queue()) {
self.editorialsTableView.reloadData()
// self.editorialsTableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.Automatic) // Animation implemented for testing, to be removed for version 1.0
}
/*
nodeIDArray[nodeCounter] = jsonValue{nodeCounter}.string
let editorialInfos : EditorialElement = ((jsonValue as! NSDictionary].1["\(nodeIDArray[nodeCounter]]"] as! [NSDictionary]].map { EditorialElement(title: $0["title"] as! String, nodeID: $0["nid"] as! Int, timeStamp: $0["revision_timestamp"] as! Int, imageURL: $0["image_url"] as! String, author: $0["author"], issueNumber: $0["issue_int"] as! Int, volumeNumber: $0["volume_int"] as! Int, articleContent: $0["html_content"] as! String] // I am going to try to break this line down to simplify it and fix the build errors
*/
}
print(self.editorialObjects.count)
}
}
/* Sorting the elements in order of newest to oldest (as the array index increases] */
self.editorialObjects.sort({ $0.timeStamp > $1.timeStamp })
let lastItem = self.editorialObjects.count
let indexPaths = (lastItem..<self.editorialObjects.count).map { NSIndexPath(forItem: $0, inSection: $0) }
dispatch_async(dispatch_get_main_queue()) {
self.editorialsTableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.Automatic) // Animation implemented for testing, to be removed for version 1.0
}
self.currentPage++
} */
}
self.populatingEditorials = false
}
}
}
Why is my app crashing once I try to load the second set of 10 objects?
EDIT 1: cellForRowAtIndexPath code
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let row = indexPath.row
/*
cell.editorialHeadlineLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline]
cell.editorialHeadlineLabel.text = editorialHeadline[row]
cell.editorialAuthorLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline]
cell.editorialAuthorLabel.text = editorialAuthor[row]
cell.editorialPublishDateLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline]
cell.editorialPublishDateLabel.text = editorialPublishDate[row]
*/
let cell = tableView.dequeueReusableCellWithIdentifier(EditorialTableCellIdentifier, forIndexPath: indexPath) as! EditorialsTableViewCell
let title = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).title
let timeStamp = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).timeStamp
let imageURL = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).imageURL
let author = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).author
let issueNumber = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).issueNumber
let volumeNumber = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).volumeNumber
let articleContent = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).articleContent
/* Unlike the Pictures Collection View, there is no need to create another Alamofire request here, since we already have all the content we want from the JSON we downloaded. There is no URL that we wish to place a request to to get extra content. */
cell.editorialHeadlineLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
cell.editorialHeadlineLabel.text = title
cell.editorialAuthorLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
cell.editorialAuthorLabel.text = author
cell.editorialPublishDateLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
cell.editorialPublishDateLabel.text = String(timeStamp)
cell.editorialVolumeAndIssueLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
cell.editorialVolumeAndIssueLabel.text = "Volume \(volumeNumber) - Issue \(issueNumber)"
return cell
}
EDIT 2: Screenshot of editorialObjects.count as I scroll down the view.

Related

How to update a specific cell label using MZDownloadManager even if user move to any ViewController and came back

I'm using MZDownloadManger library to download the files using url, every thing is working fine except the label update, when i start the downloading it changes to "Starting Downloading" then starts its progress like 10% 20% etc. its working fine but when i move to any other view controller its progress stops and not update the label value to "Downloaded". i have set a flag in my local data base '0' and '1', 0 means not downloaded and 1 means downloaded.
here is the code when a user select the cell and hit for download:
func keepOfflineFiles(sender: UIButton) {
if files[sender.tag].onLocal == "1"{
self.displayAlert(title: AlertTitle.alert, message: AlertMsg.alreadyDownloaded)
} else{
if self.files[sender.tag].status == "on amazon"{
let indexPath = IndexPath.init(row: sender.tag, section: 0)
let cell = self.tblFilesPro.cellForRow(at: indexPath)
if let cell = cell {
let downloadCell = cell as! filesTableViewCell
downloadCell.lblDetailsPro.text = "Starting Download. . ."
}
let pathString:String = ""
let fileName:String = self.files[sender.tag].file_id! + self.files[sender.tag].Extension!
if(fileName != ""){
let local_url = NSURL(fileURLWithPath: pathString.getDocumentsPath())
let filePath = local_url.appendingPathComponent(fileName)?.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath!) {
// FILE AVAILABLE
let indexPath = IndexPath.init(row: sender.tag, section: 0)
let cell = self.tblFilesPro.cellForRow(at: indexPath)
if let cell = cell {
let downloadCell = cell as! filesTableViewCell
downloadCell.lblDetailsPro.text = "Downloaded"
}
self.fileid = self.files[sender.tag].file_id!
self.updateFileStatusToRealm()
//self.displayAlert(title: AlertTitle.alert, message: AlertMsg.alreadyDownloaded)
} else {
// FILE NOT AVAILABLE
let completeUrl:String = Tray.downloadURLBasePath + self.files[sender.tag].fileLink!
if(self.verifyUrl(urlString: completeUrl)) {
self.fileid = self.files[sender.tag].file_id!
let index:String = String(sender.tag)
self.AppDelegateObj.downloadManager.addDownloadTask(fileName as String, fileURL: completeUrl as String, destinationPath: index as String)
}
}
}
}else{
self.displayAlert(title: AlertTitle.alert, message: AlertMsg.inArchiveProcess)
}
}
}
here are the delegates of MZDownloadManager that i called in AppDelegate
To update the progress
func downloadRequestDidUpdateProgress(_ downloadModel: MZDownloadModel, index: Int) {
let root : UINavigationController = self.window?.rootViewController as! UINavigationController
if let master = root.topViewController as? TabBarController {
if let nav = master.viewControllers?[0] as? FilesVC {
nav.refreshCellForIndex(downloadModel, index: Int(downloadModel.destinationPath)!)
}
} else {
print("Somthing went wrong while downloading this file.")
}
}
When downloading finished
func downloadRequestFinished(_ downloadModel: MZDownloadModel, index: Int) {
let root : UINavigationController = self.window!.rootViewController! as! UINavigationController
if let master = root.topViewController as? TabBarController {
if let nav = master.viewControllers![0] as? FilesVC{
nav.getDownloadingStatusOfCellForIndex(downloadModel, index: Int(downloadModel.destinationPath)!)
}
} else {
print("Somthing went wrong while finishing downloading of this file.")
}
}
Method to refresh the cell label
func refreshCellForIndex(_ downloadModel: MZDownloadModel, index: Int) {
let indexPath = IndexPath.init(row: index, section: 0)
let cell = self.tblFilesPro.cellForRow(at: indexPath)
if let cell = cell {
let downloadCell = cell as? filesTableViewCell
downloadCell?.updateCellForRowAtIndexPath(indexPath, downloadModel: downloadModel)
}
}
Method to get the cell and change value
func getDownloadingStatusOfCellForIndex(_ downloadModel: MZDownloadModel, index: Int) {
let indexPath = IndexPath.init(row: index, section: 0)
let cell = self.tblFilesPro.cellForRow(at: indexPath)
if let cell = cell {
let downloadCell = cell as? filesTableViewCell
downloadCell?.lblDetailsPro.text = "Downloaded"
self.fileid = self.files[index].file_id!
self.updateFileStatusToRealm()
}
}
here is the method which change the flag value 0 to 1 in database:
func updateFileStatusToRealm(){
let fileToUpdate = uiRealm.objects(filesDataTable.self).filter("file_id = %#", self.fileid)
let realm = try! Realm()
if let file = fileToUpdate.first {
try! realm.write {
file.onLocal = "1"
tblFilesPro.reloadData()
}
}
}

Multiple collectionviews in one Viewcontroller causes Index out of range error

I try to use three collectionviews in one Viewcontroller. I parse the data like the following method shows:
At the bottom i add the data depending on the position to the right list (this part works)
func getEventData(eventIDs: [String], plz: String, positiona: Int){
for eventId in eventIDs {
let ref = Database.database().reference().child("Events").child(plz).child(eventId)
ref.observe(.value, with: { snapshot in
let item = snapshot.value as? [String: AnyObject]
let eventName = item?["name"] as! String
let date = item?["date"] as! String
let lat = item?["lat"] as! String
let lng = item?["lng"] as! String
let infos = item?["additionalInfos"] as! String
let position = item?["position"] as! String
let ts = item?["ts"] as! Int
let createdBy = item?["createdBy"] as! String
let timestamp = NSDate().timeIntervalSince1970
if (ts > Int(timestamp)) {
let eo = EventObject(eventID: eventId, eventName:
eventName, info: infos, createdBy: createdBy, date: date, lat: lat, lng: lng, position: position, ts: ts)
if positiona == 0{
self.acceptedEvents.append(eo)
self.acceptedEventscv.reloadData()
}else if positiona == 1{
self.myEvents.append(eo)
self.myEventscv.reloadData()
}else if positiona == 2{
self.storedEvents.append(eo)
self.storedEventscv.reloadData()
}
}
})
}
}
In my NumbersofItemsInSection method i did the following which works as well:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == self.acceptedEventscv{
return acceptedEvents.count
}else if collectionView == self.storedEventscv{
return storedEvents.count
}else if collectionView == self.myEventscv{
return myEvents.count
}else{
return 0
}
}
and in my CellForRowAtItem method i tried the following
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == self.acceptedEventscv{
let cell =
collectionView.dequeueReusableCell(withReuseIdentifier:
"acceptedEventsCell", for: indexPath) as!
acceptedEventsCollectionViewCell
let eo = acceptedEvents[indexPath.row]
cell.eventName.text = eo.eventName
let items = eo.date!.components(separatedBy: " ")//Here replase
space with your value and result is Array.
//Direct line of code
//let items = "This is my String".components(separatedBy: " ")
let date = items[0]
let time = items[1]
cell.date.text = date
cell.time.text = time
getUserNameAge(label: cell.usernameAge)
return cell
}else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "savedEventsCell", for: indexPath) as! savedEventsCollectionViewCell
let eo = acceptedEvents[indexPath.row]
cell.eventName.text = eo.eventName
let items = eo.date!.components(separatedBy: " ")//Here replase space with your value and result is Array.
//Direct line of code
//let items = "This is my String".components(separatedBy: " ")
let date = items[0]
let time = items[1]
cell.date.text = date
cell.time.text = time
getUserNameAge(label: cell.usernameAge)
return cell
}
}
The problem is if i have more items in the seccond CollectionView, i always get this error:
Thread 1: Fatal error: Index out of range
at this line of code:
let eo = acceptedEvents[indexPath.row]
cellForItemAt also must be like
if collectionView == self.acceptedEventscv{
let item = acceptedEvents[indexPath.row]
----
return cell
}else if collectionView == self.storedEventscv{
let item = storedEvents[indexPath.row]
----
return cell
}else {
let item = myEvents[indexPath.row]
----
return cell
}
what happens now in your case is that you access the same array acceptedEvents in both cases where the returned count in numberOfItemsInSection may be different

get data from firebase children

I have two custom cells in one table view.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Configure the cell...
if (indexPath.row == 0) {
let cell = tableView.dequeueReusableCell(withIdentifier: "Main", for: indexPath) as! PostTableViewCell
//Configure the cell
cell.PostView.layer.cornerRadius = 5
cell.PostView.layer.masksToBounds = false
cell.PostView.layer.shadowColor = UIColor.black.withAlphaComponent(0.4).cgColor
cell.PostView.layer.shadowOffset = CGSize(width: 0, height: 0)
cell.PostView.layer.shadowOpacity = 0.9
let post = Comments[indexPath.row] as! [String: AnyObject]
let commentname = post["author"] as? String
sendAuthor = post["author"] as? String
cell.CommentersName.setTitle(commentname, for: .normal)
if let seconds = post["pub_time"] as? Double {
let timeStampDate = NSDate(timeIntervalSince1970: seconds/1000)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d, yyyy"
let formating = timeStampDate as Date
cell.CommentTime.text = dateFormatter.string(from: formating)
}
cell.comment.text = post["content"] as? String
textViewDidChange(cell.comment)
cell.comment.frame.size.width = 344
cell.comment.sizeToFit()
cell.comment.clipsToBounds = true
cell.REply.frame.origin.y = cell.comment.frame.maxY + 10
cell.PostView.frame.size.height = cell.comment.frame.maxY + 50
TableView.rowHeight = cell.PostView.frame.size.height + 20
cell.LikesNumber.text = post["num_likes"] as? String
replyId = post["id"] as? String
cell.checkfornightmode()
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: "Reply", for: indexPath) as! RepliesTableViewCell
cell.ReplyCustomCell.layer.cornerRadius = 5
cell.ReplyCustomCell.layer.masksToBounds = false
cell.ReplyCustomCell.layer.shadowColor = UIColor.black.withAlphaComponent(0.4).cgColor
cell.ReplyCustomCell.layer.shadowOffset = CGSize(width: 0, height: 0)
cell.ReplyCustomCell.layer.shadowOpacity = 0.9
let post = Comments[indexPath.row] as! [String: AnyObject]
let posttest = post["id"] as? String
let replyRef = Database.database().reference().child("main").child("posts").child(postID!).child("comments").child(posttest!).child("comments")
replyRef.observeSingleEvent(of: .value, with: { (snapshot:DataSnapshot) in
if let postsDictionary = snapshot .value as? [String: AnyObject] {
for testingkey in postsDictionary.keys {
Database.database().reference().child("main").child("posts").child(self.postID!).child("comments").child(posttest!).child("comments").child(testingkey).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let content : String? = value?["content"] as? String ?? ""
cell.ReplyText.text = content!
})
}
}
})
TableView.rowHeight = 150.0
return cell
}
}
The first cell with the identifier main is supposed to print out all the intial comments for a certain post. The second cell with the identifier is supposed to print out the comments to main comments. Based on this code, I am only getting the last comment of the main post and the last comment to the main posts.
This is what the json looks like
First thing is to separate the firebase call into a separate function and in that function populate a dictionary with posts as key and comments as value
for example like this
var postComments: [String: [String]] = [:] // post as key and string array as comments
In firebase database call populate this with snapshot.
After the data call but within the firebase Database call back use this function to reload data
DispatchQueue.main.async{
tableView.reloadData()
}
Set the cell with postComments array.

How to filter an array of JSON objects to be used in a table view?

I'm getting JSON data from an API and parsing that data in objects, which are then simply stored in an array of objects. The objects themselves contain data about articles from a newspaper. However, I need to filter that data. Some of the objects I'm getting from my JSON actually have no article content because they are pictures and not articles (i.e. some of the "nodes" from the API's JSON have content that I don't want to see in my table view).
In my JSON-parsing function, I've tried to make it so that the parsed object will only get added to the array of parsed objects if the character count of the "articleContent" variable is above 40. Here is what it looked like.
if issueElement.articleContent.characters.count > 40 {
self.currentIssueObjects.addObject(issueElement)
}
However, this simply does not work. I get the typical "unexpectedly found nil while unwrapping an Optional value" error message (I don't get a specific line for the error). How can I make this work ? I'm essentially trying to prevent the array from having objects with empty articleContent, because then that screws up my table view (empty cells, duplicates, etc...).
Here is my cellForRowAtIndexPath code, and my JSON-parsing code:
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell {
let row = indexPath.row
guard let cell = tableView.dequeueReusableCellWithIdentifier(CurrentIssueArticlesTableCellIdentifier, forIndexPath: indexPath) as? CurrentIssueArticlesTableViewCell else {
print ("error: currentIssueTableView cell is not of class CurrentIssueArticlesTableViewCell, we will use EditorialsTableViewCell instead")
return tableView.dequeueReusableCellWithIdentifier(CurrentIssueArticlesTableCellIdentifier, forIndexPath: indexPath) as! EditorialsTableViewCell
}
let currentIssueObject = currentIssueObjects.objectAtIndex(indexPath.row) as! IssueElement
let title = currentIssueObject.title ?? ""
let timeStampDateObject = NSDate(timeIntervalSince1970: NSTimeInterval(currentIssueObject.timeStamp))
let timeStampDateString = dateFormatter.stringFromDate(timeStampDateObject) ?? "Date unknown"
if let author = currentIssueObject.author {
cell.currentIssueArticlesAuthorLabel!.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
cell.currentIssueArticlesAuthorLabel!.text = author
}
let issueNumber = currentIssueObject.issueNumber ?? ""
let volumeNumber = currentIssueObject.volumeNumber ?? ""
let articleContent = currentIssueObject.articleContent ?? ""
let nodeID = currentIssueObject.nodeID ?? 0
cell.currentIssueArticlesHeadlineLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
cell.currentIssueArticlesHeadlineLabel.text = title
cell.currentIssueArticlesPublishDateLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
cell.currentIssueArticlesPublishDateLabel.text = timeStampDateString
if row == 0 {
cell.userInteractionEnabled = false
let imageURL = (currentIssueObjects.objectAtIndex(row) as! IssueElement).imageURL
cell.currentIssueArticlesHeadlineLabel.textColor = UIColor.clearColor()
cell.currentIssueArticlesAuthorLabel.textColor = UIColor.clearColor()
cell.currentIssueArticlesPublishDateLabel.textColor = UIColor.clearColor()
cell.request?.cancel()
if let image = self.imageCache.objectForKey(imageURL!) as? UIImage {
cell.currentIssueArticlesBackgroundImageView.image = image
} else {
cell.currentIssueArticlesBackgroundImageView.image = UIImage(named: "reveal Image")
cell.request = Alamofire.request(.GET, imageURL!).responseImage() { response in
if response.result.error == nil && response.result.value != nil {
self.imageCache.setObject(response.result.value!, forKey: response.request!.URLString)
cell.currentIssueArticlesBackgroundImageView.image = response.result.value
} else {
}
}
}
cell.currentIssueArticlesBackgroundImageView.hidden = false
}
else {
cell.currentIssueArticlesBackgroundImageView.hidden = true
}
return cell
}
JSON-parsing code:
func populateCurrentIssue() {
if populatingCurrentIssue {
return
}
populatingCurrentIssue = true
self.cellLoadingIndicator.backgroundColor = goldenWordsYellow
self.cellLoadingIndicator.startAnimating()
Alamofire.request(GWNetworking.Router.Issue).responseJSON() { response in
if let JSON = response.result.value {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
var nodeIDArray : [Int]
if (JSON .isKindOfClass(NSDictionary)) {
for node in JSON as! Dictionary<String, AnyObject> {
let nodeIDValue = node.0
var lastItem : Int = 0
self.nodeIDArray.addObject(nodeIDValue)
if let issueElement : IssueElement = IssueElement(title: "Could not retrieve title", nodeID: 0, timeStamp: 0, imageURL: "init", author: "Author not found", issueNumber: "Issue # error", volumeNumber: "Volume # error", articleContent: "Could not retrieve article content", coverImageInteger: "init", coverImage: UIImage()) {
issueElement.title = node.1["title"] as! String
issueElement.nodeID = Int(nodeIDValue)!
let timeStampString = node.1["revision_timestamp"] as! String
issueElement.timeStamp = Int(timeStampString)!
issueElement.imageURL = String(node.1["image_url"])
if let author = node.1["author"] as? String {
issueElement.author = author
}
if let issueNumber = node.1["issue_int"] as? String {
issueElement.issueNumber = issueNumber
}
if let volumeNumber = node.1["volume_int"] as? String {
issueElement.volumeNumber = volumeNumber
}
if let articleContent = node.1["html_content"] as? String {
issueElement.articleContent = articleContent
}
issueElement.coverImageInteger = String(node.1["cover_image"]) // addition specific to the Current Issue View Controller
lastItem = self.currentIssueObjects.count
print(issueElement.nodeID)
if issueElement.articleContent.characters.count > 40 {
self.currentIssueObjects.addObject(issueElement)
print(issueElement.nodeID)
}
// Sorting with decreasing timestamp from top to bottom.
let timestampSortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
self.currentIssueObjects.sortUsingDescriptors([timestampSortDescriptor])
// Placing the object with coverImage
let coverImageSortDescriptor = NSSortDescriptor(key: "coverImageInteger", ascending: false)
self.currentIssueObjects.sortUsingDescriptors([coverImageSortDescriptor])
let indexPaths = (lastItem..<self.currentIssueObjects.count).map {
NSIndexPath(forItem: $0, inSection: 0) }
}
}
}
dispatch_async(dispatch_get_main_queue()) {
self.currentIssueTableView.reloadData()
self.cellLoadingIndicator.stopAnimating()
self.cellLoadingIndicator.hidesWhenStopped = true
}
}
}
self.populatingCurrentIssue = false
}
}

Firebase function freezes app in xcode7, but works in xcode6.4

For some reason this code works perfectly in xcode6.4, but when switching to xcode7 it freezes the app.
What I am trying to do is pull the post information on a user's feed and display it on a tableview. I am able to pull the information from Firebase, but the app freezes before it displays on the tableview.
EDIT: The tableview works when I do not have any constraints or autolayout. It seems to not work when I try to have dynamic cell heights.
func getRadarData() {
let url = "https://(insert appname).firebaseio.com/users/" + currentUser + "/postsReceived/"
let targetRef = Firebase(url: url)
targetRef.observeEventType(.ChildAdded, withBlock: {
snapshot in
print("child")
if let found = self.posts.map({ $0.key }).indexOf(snapshot.key) {
let obj = self.posts[found]
print(obj)
print(found)
self.posts.removeAtIndex(found)
}
let postsUrl = "https://(insert appname).firebaseio.com/posts/" + snapshot.key
let postsRef = Firebase(url: postsUrl)
var updatedAt = snapshot.value["updatedAt"] as? NSTimeInterval
var endAt = snapshot.value["endAt"] as? NSTimeInterval
if updatedAt == nil {
updatedAt = 0
}
if endAt == nil {
endAt = 0
}
postsRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
if let key = snapshot.key
{if let content = snapshot.value["content"] as? String {
if let creator = snapshot.value["creator"] as? String {
if let createdAt = snapshot.value["createdAt"] as? NSTimeInterval {
let userurl = "https://(insert appname).firebaseio.com/users/" + (creator)
let userRef = Firebase(url: userurl)
userRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
if let username = snapshot.value["username"] as? String {
let updatedDate = NSDate(timeIntervalSince1970: (updatedAt!/1000))
let createdDate = NSDate(timeIntervalSince1970: (createdAt/1000))
let endedDate = NSDate(timeIntervalSince1970: (endAt!))
let post = Post(content: content, creator: creator, key: key, createdAt: updatedDate, name: username, joined: true, messageCount: 0, endAt: endedDate)
self.posts.append(post)
// Sort posts in descending order
self.posts.sortInPlace({ $0.createdAt.compare($1.createdAt) == .OrderedDescending })
self.tableView.reloadData()
}
})
}
}
}
}
})
})
}
Here is my code for my tableview where I used autolayout on the textView and nameLabel
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: RadarTableViewCell = tableView.dequeueReusableCellWithIdentifier("radarCell", forIndexPath: indexPath) as! RadarTableViewCell
let creator: (String) = posts[indexPath.row].creator
let key = posts[indexPath.row].key
let radarContent: (AnyObject) = posts[indexPath.row].content
cell.textView.selectable = false
cell.textView.text = radarContent as? String
cell.textView.userInteractionEnabled = false
cell.textView.selectable = true
let radarCreator: (AnyObject) = posts[indexPath.row].name
cell.nameLabel.text = radarCreator as? String
return cell
The issue was that I had initial text in my textView. I deleted it on my Storyboard and my app works now.
Found the solution here: Why does a previously working Xcode project hang up in Xcode 7 when presenting a new UITableviewController Subclass?

Resources