I got a problem with UIImage. I've manually added UIImageView objects to a scroll view. The problem is : when I have more than 50 images, memory will increase to around 200MB, and the app will be crash on iphone 4 or 4s. I want to release memory for images that is not in visible part when I receive Memory Warning to prevent crashing but I don't know how to release them with Swift. Help me please.
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loadImage(index:Int){
if self.imgPaths.count == 0 {
println("Has not data")
actInd.stopAnimating()
return
}
var imgURL: NSURL = NSURL(string: self.imgPaths[index].stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet()))!
let width:CGFloat = self.view.bounds.width
let height:CGFloat = self.view.bounds.height
var view:UIView = UIView(frame: CGRectMake(0, 0, width, height));
if let imgObj = self.dicData[index] {
}
else
{
println("imgURL \(imgURL)")
let request: NSURLRequest = NSURLRequest(URL: imgURL)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
if error == nil {
let imgItem = UIImage(data: data)!
var te :Float = self.imgPaths.count > 0 ? Float(index + 1) / Float(self.imgPaths.count) : 1
self.progressView.setProgress(te, animated: true)
if let imgObj = self.dicData[index] {
if index < self.imgPaths.count - 1
{
var nextIndex:Int = index + 1
self.loadImage(nextIndex)
}
if(index == self.imgPaths.count - 1)
{
if self.currentImageIndex > 0
{
self.isAddedFirstImg = true
}
if !self.isAddedFirstImg
{
self.scrollViews[0].zoomScale = self.zoomScales[0]
self.view.insertSubview(self.scrollViews[0], belowSubview: self.tabBar.viewWithTag(77)!)
self.isAddedFirstImg = true
}
self.actInd.stopAnimating()
println("loaded image")
}
}
else
{
self.dicData[index] = UIImageView(image: imgItem)
self.dicData[index]?.frame = CGRect(origin: CGPointMake(0.0, 0.0), size:imgItem.size)
// 2
self.scrollViews[index].addSubview(self.dicData[index]!)
self.scrollViews[index].contentSize = imgItem.size
// 3
var doubleTapRecognizer = UITapGestureRecognizer(target: self, action: "scrollViewDoubleTapped:")
doubleTapRecognizer.numberOfTapsRequired = 2
doubleTapRecognizer.numberOfTouchesRequired = 1
self.scrollViews[index].addGestureRecognizer(doubleTapRecognizer)
var singleTapRecognizer = UITapGestureRecognizer(target: self, action: "scrollViewSingleTapped:")
singleTapRecognizer.numberOfTapsRequired = 1
singleTapRecognizer.numberOfTouchesRequired = 1
self.scrollViews[index].addGestureRecognizer(singleTapRecognizer)
var swipeRight = UISwipeGestureRecognizer(target: self, action: "respondToSwipeGesture:")
swipeRight.direction = UISwipeGestureRecognizerDirection.Right
self.scrollViews[index].addGestureRecognizer(swipeRight)
var swipeLeft = UISwipeGestureRecognizer(target: self, action: "respondToSwipeGesture:")
swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
self.scrollViews[index].addGestureRecognizer(swipeLeft)
// 4
var scrollViewFrame = self.scrollViews[index].frame
var scaleWidth = scrollViewFrame.size.width / self.scrollViews[index].contentSize.width
var scaleHeight = scrollViewFrame.size.height / self.scrollViews[index].contentSize.height
var minScale = min(scaleWidth, scaleHeight)
self.zoomScales[index] = minScale
self.scrollViews[index].minimumZoomScale = minScale
// 5
self.scrollViews[index].maximumZoomScale = 1.0
self.scrollViews[index].delegate = self
// 6
self.centerScrollViewContents(index)
dispatch_async(dispatch_get_main_queue(), {
println("downloaded image index: \(index) CH.\(self.chapterID)")
if(index == 0)
{
self.scrollViews[0].zoomScale = self.zoomScales[0]
self.view.insertSubview(self.scrollViews[0], belowSubview: self.tabBar.viewWithTag(77)!)
self.actInd.stopAnimating()
}
if index < self.imgPaths.count - 1 && !self.stopDownload
{
var nextIndex:Int = index + 1
self.loadImage(nextIndex)
}
if(index == self.imgPaths.count - 1)
{
if self.currentImageIndex > 0
{
self.isAddedFirstImg = true
}
if !self.isAddedFirstImg
{
self.scrollViews[0].zoomScale = self.zoomScales[0]
self.view.insertSubview(self.scrollViews[0], belowSubview: self.tabBar.viewWithTag(77)!)
self.isAddedFirstImg = true
}
self.actInd.stopAnimating()
println("loaded image")
}
})
}
}
else {
println("Error: \(error.localizedDescription)")
}
})
}
}
Swift uses ARC (Automatic Reference Counting) to manage memory. To free something from memory, you must remove all references to that object. ARC maintains a count of the number of places that hold a reference to the object, and when that count reaches 0, the memory is freed.
In your case, your imageViews are stored in self.dicData[index] and they are added as subviews of self.scrollViews[index]. You will need to remove the imageView from its superview and from self.dicData. Once you do that, the memory will be freed.
If you have the index of the imageView you want to free:
self.dicData[index]?.removeFromSuperview()
self.dicData[index] = nil
in swift there is really good tool called "lazy"
you might wanted to study about lazy var its very handy when it comes down to the images and tableview (for your instance collectionview)
you will see a huge difference when its used from custom cell.
create a imageview e.g. lazy var imageViewer:UIImageView
my app was at about 150mb 200mb memory now its at 40~60mb try it!
Related
These are my effort:
var cats = [[String:AnyObject]]()
func getAllCats(){
_ = EZLoadingActivity.show("Loading...", disableUI: true)
let param: [String: AnyObject] = ["apiKey": "???" as AnyObject]
_ = Alamofire.request(APIRouters.GetAllCats(param)).responseJSON { (responseData) -> Void in
if((responseData.result.value) != nil) {
let getJson = JSON(responseData.result.value!)
if (getJson["status"].stringValue == "200"){
if let resData = getJson["data"].arrayObject {
self.cats = resData as! [[String:AnyObject]]
}
} else if (getJson["status"].stringValue == "404") {
} else {
}
}
_ = EZLoadingActivity.hide()
}
}
var buttonY: CGFloat = 20 // our Starting Offset, could be 0
for villain in cats {
print("ok",villain["pt_name_Fa"])
let villainButton = UIButton(frame: CGRect(x: 50, y: buttonY, width: 250, height: 30))
buttonY = buttonY + 50 // we are going to space these UIButtons 50px apart
villainButton.layer.cornerRadius = 10 // get some fancy pantsy rounding
villainButton.backgroundColor = UIColor.darkGray
villainButton.setTitle("Button for Villain: \(villain["pt_name_Fa"] ?? "" as AnyObject))", for: UIControlState.normal) // We are going to use the item name as the Button Title here.
villainButton.titleLabel?.text = "\(villain)"
villainButton.addTarget(self,action:#selector(villainButtonPressed),
for:.touchUpInside)
// villainButton.addTarget(self, action: Selector(("villainButtonPressed:")), for: UIControlEvents.touchUpInside)
self.view.addSubview(villainButton) // myView in this case is the view you want these buttons added
}
It did not work, but if i use an array such below it works!
var arrayOfVillains = ["santa", "bugs", "superman", "batman"]
Thanks for your helping in advance
I found the solution. Adding button should be run after Json load completely:
var cats = [[String:AnyObject]]()
_ = EZLoadingActivity.show("Loading...", disableUI: true)
let param: [String: AnyObject] = ["apiKey": "???" as AnyObject]
_ = Alamofire.request(APIRouters.GetAllCats(param)).responseJSON { (responseData) -> Void in
if((responseData.result.value) != nil) {
print(responseData.request!) // original URL request
print(responseData.response!) // URL response
let getJson = JSON(responseData.result.value!)
if (getJson["status"].stringValue == "200"){
if let resData = getJson["data"].arrayObject {
self.cats = resData as! [[String:AnyObject]]
}
if self.cats.count > 0 {
self.addButton()
}
} else if (getJson["status"].stringValue == "404") {
_ = SweetAlert().showAlert("Ok", subTitle: "Api Error!", style: AlertStyle.warning)
} else {
_ = SweetAlert().showAlert("Error", subTitle: getJson["message"].stringValue, style: AlertStyle.warning)
}
}
_ = EZLoadingActivity.hide()
}
func addButton(){
var buttonY: CGFloat = 20 // our Starting Offset, could be 0
for villain in self.cats {
let villainButton = UIButton(frame: CGRect(x: 50, y: buttonY, width: 250, height: 30))
buttonY = buttonY + 50 // we are going to space these UIButtons 50px apart
villainButton.layer.cornerRadius = 10 // get some fancy pantsy rounding
villainButton.backgroundColor = UIColor.darkGray
villainButton.setTitle("Button for Villain: \(villain["pt_name_Fa"] ?? "" as AnyObject))", for: UIControlState.normal) // We are going to use the item name as the Button Title here.
villainButton.titleLabel?.text = "\(villain)"
villainButton.addTarget(self,action:#selector(villainButtonPressed),
for:.touchUpInside)
self.view.addSubview(villainButton) // myView in this case is the view you want these buttons added
}
}
Please attention to this part of code :
if self.cats.count > 0 {
self.addButton()
}
Thanks for your attendance.
I have created this progressView:
progress = UIProgressView(progressViewStyle: .default)
progress.center = view.center
progress.setProgress(0.5, animated: true)
view.addSubview(progress)
In my viewDidLoad method, I call getLandGradingImages and inside that I do a loop, inside that I call getLandGradingImage for each result in getLandGradingImages, what would be the best way to update the progressView I created during this entire process:
getLandGradingImages(jobNo: jobNo) { result in
//Define axis variables
var x = 25
var y = 80
//Define image counter variable
var counterImages = 0
var actualImageCounter = 0
//For each Lot Image
for item in result
{
self.getLandGradingImage(image: item["imageBytes"] as! String) { data in
//Create Image from Data
let image = UIImage(data: data)
//Add Image to Image View
let imageView = UIImageView(image: image!)
//Set Image View Frame
imageView.frame = CGRect(x: x, y: y, width: 100, height: 100)
//Define UITapGestureRecognizer
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.imageTapped(tapGestureRecognizer:)))
//Enable user interaction
imageView.isUserInteractionEnabled = true
//Assign tap gesture to image view
imageView.addGestureRecognizer(tapGestureRecognizer)
//Add Image to view
self.view.addSubview(imageView)
//Increase x axis
x = x + 115
//Increase image counter
counterImages = counterImages + 1
actualImageCounter = actualImageCounter + 1
//If image counter is equal to 3, create new line.
if(counterImages == 3)
{
//Increase y axis
y = y + 115
//Reset x axis
x = 25
//Reset image counter
counterImages = 0
}
if(actualImageCounter == result.count)
{
//self.stopIndicator()
}
}
}
}
Here are those two methods I am calling in this process:
func getLandGradingImages(jobNo:String, completionHandler:#escaping (_ result:Array<Dictionary<String, Any>>) -> Void) {
//Define array for returning data
var returnedResults = Array<Dictionary<String, Any>>()
//Call API
WebService().GetLandGradingImages(jobNo: jobNo)
{
(result: Array<Dictionary<String, Any>>) in
DispatchQueue.main.async {
//Return our results
returnedResults = result
completionHandler(returnedResults)
}
}
}
func getLandGradingImage(image:String, completionHandler:#escaping (_ result:Data) -> Void) {
//Define array for returning data
var returnedResults = Data()
//Call API
WebService().GetLandGradingImage(image: image)
{
(result: Data) in
DispatchQueue.main.async {
//Return our results
returnedResults = result
completionHandler(returnedResults)
}
}
}
For these calls, I am using Alamofire:
func GetLandGradingImage(image: String, completion: #escaping (_ result: Data) -> Void)
{
let imagePath : String = image
let url = URL(string: webserviceImages + imagePath)!
Alamofire.request(url).authenticate(user: self.appDelegate.username!, password: self.appDelegate.password!).responseData { response in
let noData = Data()
if(response.error == nil)
{
if let data = response.data {
completion(data)
}
}
else
{
completion(noData)
}
}
}
I have tried this:
var counter:Int = 0 {
didSet {
let fractionalProgress = Float(counter) / 100.0
let animated = counter != 0
progress.setProgress(fractionalProgress, animated: animated)
}
}
and inside the for loop:
DispatchQueue.global(qos: .background).async {
sleep(1)
DispatchQueue.main.async {
self.counter = self.counter + 1
}
}
Still nothing, my the progress view appears but does not get updated.
I was searching for this issue here, and found out that this issue is not common one.
Everyone had different approaches to solve it. I'm using Firebase and Gifu framework. Actually for the last one - i copied all the files to my project, but that didn't helped either.
Here is my source code:
import FirebaseDatabase
import FirebaseAuth
import Firebase
import UIKit
import Gifu
class ViewController: UIViewController {
#IBOutlet weak var userImage: AnimatableImageView!
var displayedUserId = ""
var AcceptedOrRejected = ""
override func viewDidLoad() {
super.viewDidLoad()
let urlArray = ["http://i.imgur.com/VAWlQ0S.gif", "http://i.imgur.com/JDzGqvE.gif", "http://67.media.tumblr.com/4cd2a04b60bb867bb4746d682aa60020/tumblr_mjs2dvWX6x1rvn6njo1_400.gif", "https://media.giphy.com/media/TlK63ELk5OPDzpb6Tao/giphy.gif", "http://i3.photobucket.com/albums/y90/spicestas/GeriHalliwell-Calling-new1.gif", "http://media.tumblr.com/tumblr_lnb9aozmM71qbxrlp.gif"]
var counter = 1
for url in urlArray {
let nsUrl = NSURL(string: url)
let girls = ProfileClass()
girls.profilePhotoUrl = url
girls.profileGender = "female"
girls.profileName = "girlsname\(counter)"
girls.profileSurname = "girlsurname\(counter)"
girls.interest = "men"
girls.uid = "\(randomStringWithLength(45))"
counter++
girls.SaveUser()
}
//----setting variables
let label = UILabel(frame: CGRectMake(self.view.bounds.width / 2 - 100, self.view.bounds.height / 2 - 50, 300, 100))
//label.text = "Drag me!"
//label.textAlignment = NSTextAlignment.Center
self.view.addSubview(label)
let gesture = UIPanGestureRecognizer(target: self, action: Selector("wasDragged:"))
userImage.addGestureRecognizer(gesture)
userImage.userInteractionEnabled = true
//----getting access to database
let thisUserRef = URL_BASE.childByAppendingPath("profile")
thisUserRef.queryOrderedByChild("Interest").queryEqualToValue("men").observeEventType(.Value, withBlock: {
snapshot in
for child in snapshot.children{
self.displayedUserId = (child.value["uid"] as? String)!
let imageURL = child.value["photo"] as? String
let imURL = NSURL(string: imageURL!)
//print(imageURL)
if self.AcceptedOrRejected != "" {
let AcceptedArray = child.value[AcceptedOrRejected] as? Array
AcceptedArray.append(displayedUserId)
}
if let picData = NSData(contentsOfURL: imURL!) {
self.userImage.animateWithImageData(picData)
//self.userImage.image = UIImage(data: picData)
}
}
})
}
//-----Dragging function-----------
func wasDragged(gesture: UIPanGestureRecognizer) {
//set traslations
let translation = gesture.translationInView(self.view)
let label = gesture.view
//set center position
label!.center = CGPoint(x: self.view.bounds.width / 2 + translation.x, y: self.view.bounds.height / 2 - translation.y )
let xfromCenter = (label?.center.x)! - self.view.bounds.width / 2
let scale = min(100 / abs(xfromCenter),1)
var rotation = CGAffineTransformMakeRotation(xfromCenter / 200)
var strech = CGAffineTransformScale(rotation, scale, scale)
label?.transform = strech
if gesture.state == UIGestureRecognizerState.Ended {
if label?.center.x < 100 {
self.AcceptedOrRejected = "Accepted"
} else if label?.center.x > self.view.bounds.width / 100 {
self.AcceptedOrRejected = "Rejected"
}
rotation = CGAffineTransformMakeRotation(0)
strech = CGAffineTransformScale(rotation, 1, 1)
label?.transform = strech
label?.center = CGPoint(x: self.view.bounds.width / 2 , y: self.view.bounds.height / 2 )
}
}
//---Function for generating randomn userid
func randomStringWithLength (len : Int) -> NSString {
let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomString : NSMutableString = NSMutableString(capacity: len)
for (var i=0; i < len; i += 1){
let length = UInt32 (letters.length)
let rand = arc4random_uniform(length)
randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
}
return randomString
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "LogOutSegue" {
try! FIRAuth.auth()!.signOut()
}
}
}
And I get this error
1. While emitting SIL for 'viewDidLoad' at /Users/zkid18/Desktop/wrk/Bloom/Bloom/ViewController.swift:23:14
2. While silgen closureexpr SIL function #_TFFC5Bloom14ViewController11viewDidLoadFT_T_U_FCSo15FIRDataSnapshotT_ for expression at [/Users/zkid18/Desktop/wrk/Bloom/Bloom/ViewController.swift:68:114 - line:107:9] RangeText="{
snapshot in
for child in snapshot.children{
self.displayedUserId = (child.value["uid"] as? String)!
let imageURL = child.value["photo"] as? String
let imURL = NSURL(string: imageURL!)
//print(imageURL)
if self.AcceptedOrRejected != "" {
let AcceptedArray = child.value[AcceptedOrRejected] as? Array
AcceptedArray.append(displayedUserId)
}
if let picData = NSData(contentsOfURL: imURL!) {
self.userImage.animateWithImageData(picData)
//self.userImage.image = UIImage(data: picData)
}
}
}"
I don't really know what to do with that
I just attempted a conversion to Swift 3 to get a jump on fixing issues in my code. I have similar error but I just integrated Firebase into all of my project. I found that by removing the pod and framework from the app and commenting out all firebase code fixed this compile issue.
Initially I had this code working when I was just animating the one UIImageView that I had. But then I changed it to animate several dynamically created UIImageViews, however since they are dynamically created inside a for loop, I'm finding it difficult to animate them as I did the initial one.
override func viewDidLoad() {
super.viewDidLoad()
var sprite: UIImage = UIImage(named: "sprites/areaLocatorSprite.png")!
var locations:NSArray = animal[eventData]["locations"] as NSArray
for var i = 0; i < locations.count; i++ {
println(locations[i]["locationx"])
var locationx = locations[i]["locationx"] as String
var locationy = locations[i]["locationy"] as String
let x = NSNumberFormatter().numberFromString(locationx)
let y = NSNumberFormatter().numberFromString(locationy)
let cgfloatx = CGFloat(x!)
let cgfloaty = CGFloat(y!)
var mapSprite: UIImageView
mapSprite = UIImageView(image: sprite)
mapSprite.frame = CGRectMake(cgfloatx,cgfloaty,10,10)
townMap.addSubview(mapSprite)
timer = NSTimer.scheduledTimerWithTimeInterval(0.35, target: self, selector: Selector("flash"), userInfo: nil, repeats: true)
}
}
func flash() {
var mapSprite:UIImageView?
if mapSprite?.alpha == 1 {
mapSprite?.alpha = 0
} else {
mapSprite?.alpha = 1
}
}
This does not work as the mapSprite in the flash function is different to the one in the for loop. How can I refer to the one in the for loop and then animate it? Or would there be a better alternative to what I'm currently doing?
Many thanks!
EDIT
Using Xcode 6.2
You need to store the views into a property and then enumerate that property each time your timer event is fired
var sprites: [UIImageView]?
override func viewDidLoad() {
super.viewDidLoad()
var sprite = UIImage(named: "sprites/areaLocatorSprite.png")!
var locations:NSArray = animal[eventData]["locations"] as NSArray
self.sprites = map(locations) {
var locationx = $0["locationx"] as String
var locationy = $0["locationy"] as String
let x = NSNumberFormatter().numberFromString(locationx)
let y = NSNumberFormatter().numberFromString(locationy)
let cgfloatx = CGFloat(x!)
let cgfloaty = CGFloat(y!)
var mapSprite = UIImageView(image: sprite)
mapSprite.frame = CGRectMake(cgfloatx,cgfloaty,10,10)
townMap.addSubview(mapSprite)
return mapSprite
}
timer = NSTimer.scheduledTimerWithTimeInterval(0.35, target: self, selector: Selector("flash"), userInfo: nil, repeats: true)
}
func flash() {
if let sprites = self.sprites {
for sprite in sprites {
sprite.alpha = sprite.alpha == 0 ? 1 : 0
}
}
}
I'm following along with Rob Percival's tutorial on Udemy and my app crashes with a fatal error: cannot index empty buffer.
The error happens on the following line in the ViewdidLoad method:
userImage.image = UIImage(data: self.userImages[0])
Using println(self.userImages) right above that erroneous line I found out the array is empty. The console outputs a []. This must be why it's crashing. Correct?
My Parse.com dashboard shows that all my users have images. I'm not sure why the array would be empty. Any ideas?
import UIKit
class SwipeViewController: UIViewController {
var xFromCenter: CGFloat = 0
var usernames = [String]()
var userImages = [NSData]()
var currentUser = 0
override func viewDidLoad() {
super.viewDidLoad()
println(PFUser.currentUser()["first_name"])
PFGeoPoint.geoPointForCurrentLocationInBackground { (geopoint: PFGeoPoint!, error: NSError!) -> Void in
println(error)
if error == nil {
println(geopoint)
var user = PFUser.currentUser()
user["location"] = geopoint
var query = PFUser.query()
query.whereKey("location", nearGeoPoint:geopoint)
query.limit = 10
query.findObjectsInBackgroundWithBlock({ (users, error) -> Void in
for user in users {
var gender1 = user["gender"] as? NSString
var gender2 = PFUser.currentUser()["interestedIn"] as? NSString
if gender1 == gender2 && PFUser.currentUser().username != user.username {
self.usernames.append(user.username)
// Update - chaned as to as!
self.userImages.append(user["image"] as NSData)
}
}
var userImage: UIImageView = UIImageView(frame: CGRectMake(0, 0, self.view.frame.width, self.view.frame.height))
println("images:")
println(userImage)
println(self.userImages)
userImage.image = UIImage(data: self.userImages[0])
userImage.contentMode = UIViewContentMode.ScaleAspectFit
self.view.addSubview(userImage)
var gesture = UIPanGestureRecognizer(target: self, action: Selector("wasDragged:"))
userImage.addGestureRecognizer(gesture)
userImage.userInteractionEnabled = true
})
user.save()
}
}
}
func wasDragged(gesture: UIPanGestureRecognizer) {
let translation = gesture.translationInView(self.view)
var label = gesture.view!
xFromCenter += translation.x
var scale = min(100 / abs(xFromCenter), 1)
label.center = CGPoint(x: label.center.x + translation.x, y: label.center.y + translation.y)
gesture.setTranslation(CGPointZero, inView: self.view)
var rotation:CGAffineTransform = CGAffineTransformMakeRotation(xFromCenter / 200)
var stretch:CGAffineTransform = CGAffineTransformScale(rotation, scale, scale)
label.transform = stretch
if label.center.x < 100 {
println("Not Chosen")
} else if label.center.x > self.view.bounds.width - 100 {
println("Chosen")
}
if gesture.state == UIGestureRecognizerState.Ended {
self.currentUser++
label.removeFromSuperview()
if self.currentUser < self.userImages.count {
var userImage: UIImageView = UIImageView(frame: CGRectMake(0, 0, self.view.frame.width, self.view.frame.height))
userImage.image = UIImage(data: self.userImages[self.currentUser])
userImage.contentMode = UIViewContentMode.ScaleAspectFit
self.view.addSubview(userImage)
var gesture = UIPanGestureRecognizer(target: self, action: Selector("wasDragged:"))
userImage.addGestureRecognizer(gesture)
userImage.userInteractionEnabled = true
xFromCenter = 0
} else {
println("No more users")
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Looks like a data issue. The problem must comes from the loop just above the failing line.
Conditions are not met, and so no image is pushed into the array. Reasons can be:
You only have 1 user (your current user)
There is no other users with a gender that meets the "interested in" condition of your current user
Your users (current or not) doesn't have the "gender" or "interestedIn" attributes set
The best way is to put breakpoint (or log) inside your loop in order to determine users gender and "interestedIn" attributes and see if there is some matches.