Is this warning anything that I should be concerned about?
If so what would be a solution?
this is my function :
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? ProfileViewController{
let cell = sender as! UITableViewCell
let selectedRow = myTableView.indexPath(for: cell)!.row
switch (mySegmentedControl.selectedSegmentIndex){
case 0:
destination.nameVar = userSFList[selectedRow].name!
destination.imageOneURL = userSFList[selectedRow].image!
destination.bioVar = userSFList[selectedRow].bio!
if let image2 = userSFList[selectedRow].imageTwo {
destination.imageTwoUrl = image2 }
if let contactInt = userSFList[selectedRow].contact as? Int {
destination.contact = contactInt
}
break
case 1:
destination.nameVar = userEBList[selectedRow].name!
destination.imageOneURL = userEBList[selectedRow].image!
destination.imageTwoUrl = userEBList[selectedRow].imageTwo!
if let contactInt = userEBList[selectedRow].contact as? Int {
destination.contact = contactInt
}
break
case 2:
destination.nameVar = userSFOList[selectedRow].name!
destination.imageOneURL = userSFOList[selectedRow].image!
if let contactInt = userSFOList[selectedRow].contact as? Int {
destination.contact = contactInt
}
break
case 3:
destination.nameVar = userSJList[selectedRow].name!
destination.imageOneURL = userSJList[selectedRow].image!
if let contactInt = userSJList[selectedRow].contact as? Int {
destination.contact = contactInt
}
break
default:
break
}
}
}
I am using a segmented control with four different segments and pulling the data using firebase.
My personal rule is always zero warnings.
Better safe than sorry.
Is contact an Optional? If so...
You could use Optional Binding:
if let contactInt = userSFOList[selectRow].contact as? Int {
destination.contact = contactInt
}
Or the Nil-Coalescing Operator:
destination.contact = userSFOList[selectedRow].contact.intValue ?? <Your default Int here>
You could also use guard as pointed out by #Kamil.S, like:
guard let nameVar = userSFOList[selectedRow].name,
let imageVar = userSFOList[selectedRow].image,
let contactVar = contact as? Int else {
// Conditions were failed. `return` or `throw`.
}
destination.nameVar = nameVar
destination.imageOneURL = imageVar
destination.contact = contactVar
Related
I have multiple query snapshots with closures and some of them are using the data supplied by the query that came before it.
I have read up on GCD and I've tried to implement a DispatchGroup with .enter() and .leave() but I am apparently doing something wrong.
If somebody can help me by laying out exactly how to force one task to be performed before another, that would solve my problem.
If you can't tell, I am somewhat new to this so any help is greatly appreciated.
//MARK: Get all userActivities with distance(All Code)
static func getAllChallengesWithDistanceAllCode(activity:String, completion: #escaping ([Challenge]) -> Void) {
let db = Firestore.firestore()
let currUserID = Auth.auth().currentUser!.uid
var currUserName:String?
var distanceSetting:Int?
var senderAverage:Double?
var senderBestScore:Int?
var senderMatchesPlayed:Double?
var senderMatchesWon:Double?
var senderWinPercentage:Double?
var validUserActivities = [Challenge]()
db.collection("users").document(currUserID).getDocument { (snapshot, error) in
if error != nil || snapshot == nil {
return
}
currUserName = snapshot?.data()!["userName"] as? String
distanceSetting = snapshot?.data()!["distanceSetting"] as? Int
}
db.collection("userActivities").document(String(currUserID + activity)).getDocument { (snapshot, error) in
//check for error
//MARK: changed snapshot to shapshot!.data() below (possible debug tip)
if error != nil {
//is error or no data..??
return
}
if snapshot!.data() == nil {
return
}
//get profile from data proprty of snapshot
if let uActivity = snapshot!.data() {
senderBestScore = uActivity["bestScore"] as? Int
senderMatchesPlayed = uActivity["played"] as? Double
senderMatchesWon = uActivity["wins"] as? Double
senderAverage = uActivity["averageScore"] as? Double
senderWinPercentage = round((senderMatchesWon! / senderMatchesPlayed!) * 1000) / 10
}
}
if distanceSetting != nil {
db.collection("userActivities").whereField("activity", isEqualTo: activity).getDocuments { (snapshot, error) in
if error != nil {
print("something went wrong... \(String(describing: error?.localizedDescription))")
return
}
if snapshot == nil || snapshot?.documents.count == 0 {
print("something went wrong... \(String(describing: error?.localizedDescription))")
return
}
if snapshot != nil && error == nil {
let uActivitiesData = snapshot!.documents
for uActivity in uActivitiesData {
let userID = uActivity["userID"] as! String
UserService.determineDistance(otherUserID: userID) { (determinedDistance) in
if determinedDistance! <= distanceSetting! && userID != currUserID {
var x = Challenge()
//Sender
x.senderUserID = currUserID
x.senderUserName = currUserName
x.senderAverage = senderAverage
x.senderBestScore = senderBestScore
x.senderMatchesPlayed = senderMatchesPlayed
x.senderMatchesWon = senderMatchesWon
x.senderWinPercentage = senderWinPercentage
//Receiver
x.receiverUserID = userID
x.receiverUserName = uActivity["userName"] as? String
x.receiverAverage = uActivity["averageScore"] as? Double
x.receiverBestScore = uActivity["bestScore"] as? Int
if (uActivity["played"] as! Double) < 1 || (uActivity["played"] as? Double) == nil {
x.receiverMatchesPlayed = 0
x.receiverMatchesWon = 0
x.receiverWinPercentage = 0
} else {
x.receiverMatchesPlayed = uActivity["played"] as? Double
x.receiverMatchesWon = uActivity["wins"] as? Double
x.receiverWinPercentage = ((uActivity["wins"] as! Double) / (uActivity["played"] as! Double) * 1000).rounded() / 10
}
if uActivity["playStyle"] as? String == nil {
x.receiverPlayStyle = "~No PlayStyle~"
} else {
x.receiverPlayStyle = uActivity["playStyle"] as! String
}
x.activity = activity
//append to array
validUserActivities.append(x)
}
}
}
completion(validUserActivities)
}
}
}
}
try this
static func getAllChallengesWithDistanceAllCode(activity:String, completion: #escaping ([Challenge]) -> Void) {
let db = Firestore.firestore()
let currUserID = Auth.auth().currentUser!.uid
var currUserName:String?
var distanceSetting:Int?
var senderAverage:Double?
var senderBestScore:Int?
var senderMatchesPlayed:Double?
var senderMatchesWon:Double?
var senderWinPercentage:Double?
var validUserActivities = [Challenge]()
db.collection("users").document(currUserID).getDocument { (snapshot, error) in
if error != nil || snapshot == nil {
return
}
currUserName = snapshot?.data()!["userName"] as? String
distanceSetting = snapshot?.data()!["distanceSetting"] as? Int
db.collection("userActivities").document(String(currUserID + activity)).getDocument { (snapshot, error) in
//check for error
//MARK: changed snapshot to shapshot!.data() below (possible debug tip)
if error != nil {
//is error or no data..??
return
}
if snapshot!.data() == nil {
return
}
//get profile from data proprty of snapshot
if let uActivity = snapshot!.data() {
senderBestScore = uActivity["bestScore"] as? Int
senderMatchesPlayed = uActivity["played"] as? Double
senderMatchesWon = uActivity["wins"] as? Double
senderAverage = uActivity["averageScore"] as? Double
senderWinPercentage = round((senderMatchesWon! / senderMatchesPlayed!) * 1000) / 10
if snapshot != nil && error == nil {
let uActivitiesData = snapshot!.documents
for uActivity in uActivitiesData {
let userID = uActivity["userID"] as! String
UserService.determineDistance(otherUserID: userID) { (determinedDistance) in
if determinedDistance! <= distanceSetting! && userID != currUserID {
var x = Challenge()
//Sender
x.senderUserID = currUserID
x.senderUserName = currUserName
x.senderAverage = senderAverage
x.senderBestScore = senderBestScore
x.senderMatchesPlayed = senderMatchesPlayed
x.senderMatchesWon = senderMatchesWon
x.senderWinPercentage = senderWinPercentage
//Receiver
x.receiverUserID = userID
x.receiverUserName = uActivity["userName"] as? String
x.receiverAverage = uActivity["averageScore"] as? Double
x.receiverBestScore = uActivity["bestScore"] as? Int
if (uActivity["played"] as! Double) < 1 || (uActivity["played"] as? Double) == nil {
x.receiverMatchesPlayed = 0
x.receiverMatchesWon = 0
x.receiverWinPercentage = 0
} else {
x.receiverMatchesPlayed = uActivity["played"] as? Double
x.receiverMatchesWon = uActivity["wins"] as? Double
x.receiverWinPercentage = ((uActivity["wins"] as! Double) / (uActivity["played"] as! Double) * 1000).rounded() / 10
}
if uActivity["playStyle"] as? String == nil {
x.receiverPlayStyle = "~No PlayStyle~"
} else {
x.receiverPlayStyle = uActivity["playStyle"] as! String
}
x.activity = activity
//append to array
validUserActivities.append(x)
}
}
}
completion(validUserActivities)
}
}
}
}
}
}
}
I solved this by doing the following:
Add a constant before the for-in loop counting the total number of query results
let documentCount = snapshot?.documents.count
Add a counter before the for-in loop starting at 0
var runCounter = 0
Increment the counter with each iteration at the beginning of the for-in loop
runCounter += 1
Add code to the end of the for-in loop to call the completion handler to return the results
if runCounter == documentCount {
completion(validChallenges)
}
I have a follow/unfollow button and am accessing it by "sender". I am changing the text when the user taps it to follow or unfollow another user. Problem is that when it should show "unfollow" it is showing the default text used in storyboard. The button changes to "follow" as it should, but not "unfollow". Also, I have to use "sender: UIButton" because I am accessing the tableview cells "tag" for the right information.
#IBAction func followButton(_ sender: UIButton) {
//self.yourFollowing.removeAll()
//self.following.removeAll()
self.followingTableView.reloadData()
let accessData = self.yourFollowing[sender.tag].dataPass
let businessUid = accessData["uid"] as! String
let businessName = accessData["businessName"] as! String
let businessStreet = accessData["businessStreet"] as! String
let businessCity = accessData["businessCity"] as! String
let businessState = accessData["businessState"] as! String
let businessZip = accessData["businessZIP"] as! String
let businessPhone = accessData["businessPhone"] as! String
let businessLatitude = accessData["businessLatitude"] as! String
let businessLongitude = accessData["businessLongitude"] as! String
let businessWebsite = accessData["businessWebsite"] as! String
let businessFacebook = accessData["facebookURL"] as! String
let businessFoursquare = accessData["foursquareURL"] as! String
let businessGoogle = accessData["googleURL"] as! String
let businessInstagram = accessData["instagramURL"] as! String
let businessSnapchat = accessData["snapchatURL"] as! String
let businessTwitter = accessData["twitterURL"] as! String
let businessYelp = accessData["yelpURL"] as! String
let userID = Auth.auth().currentUser!.uid
let ref = Database.database().reference()
let key = ref.child("Businesses").childByAutoId().key
var isFollower = false
let followersRef = "followers/\(businessUid)/\(self.loggedInUserData?["uid"] as! String)"
let followingRef = "following/" + (self.loggedInUserData?["uid"] as! String) + "/" + (businessUid)
ref.child("Businesses").child(userID).child("following").queryOrderedByKey().observeSingleEvent(of: .value, with: { snapshot in
if let following = snapshot.value as? [String : AnyObject] {
for (item, value) in following {
if value as! String == businessUid {
isFollower = true
let followersRef = "followers/\(businessUid)/\(self.loggedInUserData?["uid"] as! String)"
let followingRef = "following/" + (self.loggedInUserData?["uid"] as! String) + "/" + (businessUid)
let childUpdates = [followingRef:NSNull(),followersRef:NSNull()]
self.databaseRef.updateChildValues(childUpdates)
ref.child("Businesses").child(userID).child("following/\(item)").removeValue()
ref.child("Businesses").child(businessUid).child("followers/\(item)").removeValue()
sender.titleLabel?.text = "follow"
//self.yourFollowing.removeAll()
self.following.removeAll()
self.followingTableView.reloadData()
}
}
}
// Follow
if !isFollower {
sender.titleLabel?.text = "unfollow"
let followersData = ["email":self.loggedInUserData?["email"] as! String, "businessName":self.loggedInUserData?["businessName"] as! String]
let followingData = ["businessName":businessName, "businessStreet":businessStreet, "businessCity":businessCity, "businessState":businessState, "businessZIP":businessZip, "businessPhone":businessPhone, "businessWebsite":businessWebsite,"businessLatitude":businessLatitude, "businessLongitude":businessLongitude, "facebookURL":businessFacebook, "twitterURL":businessTwitter, "instagramURL":businessInstagram, "googleURL":businessGoogle, "yelpURL":businessYelp, "foursquareURL":businessFoursquare, "snapchatURL":businessSnapchat, "uid":businessUid]
let childUpdates = [followersRef:followersData, followingRef:followingData]
self.databaseRef.updateChildValues(childUpdates)
let following = ["following/\(key)" : businessUid]
let followers = ["followers/\(key)" : userID]
ref.child("Businesses").child(userID).updateChildValues(following as Any as! [AnyHashable : Any])
ref.child("Businesses").child(businessUid).updateChildValues(followers)
self.yourFollowing.removeAll()
self.following.removeAll()
self.followingTableView.reloadData()
}
})
}
Your problem is this line in your button action
#IBAction func followButton(_ sender: UIButton) {
.
.
var isFollower = false
.
.
}
You are declaring the variable isFollow inside the button action. This means that every time regardless of follow or unfollow, your isFollower is false which is why the condition for follow will work. But the change to true which is inside the completion of follow won't reflect next time you click the button because you are resetting isFollower to false.
Solution: Move the variable isFollow outside the button action.
var isFollow = false
#IBAction func followButton(_ sender: UIButton) {
// Your logic
}
Also your logic inside the completion seems wrong. Something like the code below should be there to change it to false.
if value as! String == businessUid {
isFollower = !isFollower
if isFollower {
// Follow logic
sender.setTitle("unfollow", for: .normal)
} else {
// Unfollowed logic
sender.setTitle("follow", for: .normal)
}
// Reload table
}
here i had divided into sections in it each section there are rows depending on count so for every row the radio button will be there and i need to make active only one radio button for all of the sections but i am unable to implement it and the image for sections will be shown here and my code is
#IBAction func paymentRadioAction(_ sender: KGRadioButton) {
let chekIndex = self.checkIsPaymentRadioSelect.index(of: sender.tag)
if sender.isSelected {
} else{
if(chekIndex == nil){
self.checkIsPaymentRadioSelect.removeAll(keepingCapacity: false)
self.checkIsPaymentRadioSelect.append(sender.tag)
self.shippingTableView.reloadData()
}
}
}
here is the code for cell for row at indexpath
let cell = tableView.dequeueReusableCell(withIdentifier: "shippingCell", for: indexPath) as! shippingMethodTableViewCell
var key = self.keys[indexPath.section]
print(key)
var a :[Any] = arrayss[key] as! [Any]
var dictionary = a[indexPath.row] as! [String:Any]
let name = dictionary["name"]
let price = dictionary ["price"]
cell.methodNameLabel.text = name as! String
cell.priceLabel.text = price as! String
let checkIndex = self.checkIsPaymentRadioSelect.index(of: indexPath.row)
if(checkIndex != nil){
cell.radioButton.isSelected = true
}else{
cell.radioButton.isSelected = false
}
return cell
}
Here you don't have to use an array to keep track of the selected radio button
Make chekIndex as global variable of type IndexPath as var chekIndex:IndexPath?
and modify the code as below
#IBAction func paymentRadioAction(_ sender: KGRadioButton) {
let center = sender.center;
let centralPOint = sender.superview?.convert(sender.center, to:self.shippingTableView )
let indexPath = self.shippingTableView.indexPathForRow(at: centralPoint)
if sender.isSelected {
} else{
chekIndex = indexPath
self.shippingTableView.reloadData()
}
}
let cell = tableView.dequeueReusableCell(withIdentifier: "shippingCell", for: indexPath) as! shippingMethodTableViewCell
var key = self.keys[indexPath.section]
print(key)
var a :[Any] = arrayss[key] as! [Any]
var dictionary = a[indexPath.row] as! [String:Any]
let name = dictionary["name"]
let price = dictionary ["price"]
cell.methodNameLabel.text = name as! String
cell.priceLabel.text = price as! String
if checkIndex == indexPath {
cell.radioButton.isSelected = true
} else {
cell.radioButton.isSelected = false
}
return cell
}
I have a UITableView with 2 prototype cells: CourseCell and BllCell. These cells contain a UISlider and an IBAction is in place on the main ViewController.
After the slider has finished moving the following action is triggered:
#IBAction func sliderFinishedMoving(_ sender: Any) {
if let slider = sender as? gradeSlider {
if let superview = slider.superview {
if let cell = superview.superview as? CourseCell {
let selectedSemester = cell.activeSemester
let selectedIndexPath = courseTable.indexPath(for: cell)!
let selectedCourse = courseTypes[selectedIndexPath.section].courses[selectedIndexPath.row]
if selectedCourse.examType == "" && selectedCourse.examCourse == true {
print("please select the exam type before entering grades")
slider.value = 0.0
cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)
cell.gradeSliderLabel.text = "0"
return
}
print(selectedIndexPath.section, selectedIndexPath.row)
slider.value = round(slider.value)
cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)
switch(selectedSemester) {
case 1:
selectedCourse.semester1Grade = Int(slider.value)
break
case 2:
selectedCourse.semester2Grade = Int(slider.value)
break
case 3:
selectedCourse.semester3Grade = Int(slider.value)
break
case 4:
selectedCourse.semester4Grade = Int(slider.value)
break
case 5:
selectedCourse.examGrade = Int(slider.value)
break
case 6:
selectedCourse.oralGrade = Int(slider.value)
break
default:
break
}
courseTable.reloadData()
}
if let cell = superview.superview as? BllCell {
let selectedSemester = cell.activeSemester
let selectedIndexPath = courseTable.indexPath(for: cell)!
let selectedCourse = courseTypes[selectedIndexPath.section].courses[selectedIndexPath.row]
if selectedCourse.examType == "" && selectedCourse.examCourse == true {
print("please select the exam type before entering grades")
slider.value = 0.0
cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)
cell.gradeSliderLabel.text = "0"
return
}
print(selectedIndexPath.section, selectedIndexPath.row)
slider.value = round(slider.value)
cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)
switch(selectedSemester) {
case 1:
selectedCourse.semester1Grade = Int(slider.value)
break
case 2:
selectedCourse.semester2Grade = Int(slider.value)
break
case 3:
selectedCourse.semester3Grade = Int(slider.value)
break
case 4:
selectedCourse.semester4Grade = Int(slider.value)
break
case 5:
selectedCourse.examGrade = Int(slider.value)
break
case 6:
selectedCourse.oralGrade = Int(slider.value)
break
default:
break
}
courseTable.reloadData()
}
}
}
}
As you can see, there is duplicate code. Is it possible to fire if let cell ... with both CourseCell and BllCell in order to access the cell.activeSemester variable in both without having to duplicate the function?
You have to make a common parent for both BllCell CourseCell if you are performing the same instruction.
There are numerous issues with this code but the immediate answer to your specific question is to use a protocol:
protocol GradeSliderCell: class {
var activeSemester: Int { get }
var gradeSliderLabel: UILabel! { get }
}
Both CourseCell and BllCell should conform to this protocol.
That cuts the duplicated code in half:
#IBAction func sliderFinishedMoving(_ sender: Any) {
guard let slider = sender as? gradeSlider else { return }
guard let superview = slider.superview else { return }
if let cell = superview.superview as? GradeSliderCell {
let selectedSemester = cell.activeSemester
let selectedIndexPath = courseTable.indexPath(for: cell as! UITableViewCell)!
let selectedCourse = courseTypes[selectedIndexPath.section].courses[selectedIndexPath.row]
if selectedCourse.examType == "" && selectedCourse.examCourse == true {
print("please select the exam type before entering grades")
slider.value = 0.0
cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)
cell.gradeSliderLabel.text = "0"
return
}
print(selectedIndexPath.section, selectedIndexPath.row)
slider.value = round(slider.value)
cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)
switch(selectedSemester) {
case 1:
selectedCourse.semester1Grade = Int(slider.value)
case 2:
selectedCourse.semester2Grade = Int(slider.value)
case 3:
selectedCourse.semester3Grade = Int(slider.value)
case 4:
selectedCourse.semester4Grade = Int(slider.value)
case 5:
selectedCourse.examGrade = Int(slider.value)
case 6:
selectedCourse.oralGrade = Int(slider.value)
default:
break
}
courseTable.reloadData()
}
}
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
}
}