Image not displaying in image view - ios

I have an iPhone application that displays details of local businesses. I read the business details from a .csv file to first show all businesses in a UITableViewController, and then depending on the selection, show the details for each business in a UIViewController.
All information is displaying and working as intended, except for my images - they are not displaying. I have created an IBOutlet for them same as for all the other labels and this is how I set the image in the UIViewController in viewDidLoad():
self.businessImage.image
= [UIImage imageNamed:businessDetailContent.imageName];
Where businessDetailContent.imageName is a NSObject that holds the business' details.
All images are also imported and present. When I NSLog after the above code, I can see the image is present, but its not showing up on my UIViewController.
And here is how the information in the .csv file looks
ID, name, address, tel, email, URL, description, hotel_someHotelName
Where hotel_someHotelName is the name of the image file (hotel_someHotelName.jpg).
I have tried adding the .jpg extension to the end of hotel_someHotelName in .csv but still no image.
Some of the images are low quality, so may this be the issue?

You are saying:
self.businessImage.image = [UIImage imageNamed:businessDetailContent.imageName];
And no image is appearing in your interface. So there are three possibilities:
[UIImage imageNamed:businessDetailContent.imageName] is nil
self.businessImage is nil
self.businessImage is a nonnil image view, and you are successfully assigning it an image, but that image view is not in your interface (or constraints are resizing it to zero size so that it is effectively invisible)
The first two may be readily tested by careful logging. One way to test the third possibility is to give the image view a colored background (set its backgroundColor; you can do this in Interface Builder too). If you still don't see it, that's the problem.

Just found my issue. In my .csv file, the image name had a space after the image name. When I removed this space (purely found by accident), the images are working fine.
Thanks for all the help all the same

Related

How to test if a UIImageView contains an image with a specific name using XCUITest?

I have a collectionView that has a bunch of cells that contain a single UIImageView in each cell. I want to test wether or not in each cell, the imageView's image matches the correct image name.
In the production code, I've added an accessibility identifier to the UIImageView example: "My Image View". I loop through an array of strings containing image names and set the cell's image in accordance to the index, example: ["image0.png", "image1.png", "image2.png"] so cells at index 0-2 would have those images respectively.
In my XCUITest file I'm trying something like this:
XCTAssert(cells.images["My Image View"].exists, "message here")
But this doesn't check if the cell's imageView has the right image. Can anyone suggest a better solution?
Some references I visited beforehand:
How to test UIImageView elements in iOS XCTest?
XCUIElement - Obtain Image value
I apologize if this question has been asked before, I couldn't find anything.
Edit:
I found a solution.
let image = cells.element(matching: , identifier: )
I didn't know that the identifier parameter actually uses the image name so If I pass the image name, I can assert the existence of the image.
let image = cells.element(matching: .image, identifier: "myImage.png")
this works. So when I loop through an array of strings containing the image name, I can also check if the cell at the index corresponding to the image index is correct.
I also forgot to mention that the images aren't being stored in assets, but are being fetched via json.
cesarmarch's answer below was the closest so I marked that as correct.
XCTest UI tests are designed to be written as functional tests, rather than checking that the display is correct. Since the image doesn't exhibit a behaviour for the UI test to observe, a UI test isn't the best tool for the job.
In this case, you should write unit tests to assert that the correct image is assigned to your image views, as unit tests will have access to the right level of information to allow you to inspect the data you pass to your view presentation layer and assert that the assigned image is the one you expect.
I just use something like
XCTAssert(cells.images["Image_Name_In_Resource_Directory"].exists, "message here")
to check if the current image is the good to use and it works fine.
All the images in the project are exported into the app bundle while building. Have a folder under your UI Testing group to contain all the expected images to be verified and a dummy image file.
var url = Bundle(for: AnyClass.self).url(forResource: "<ExpectedImageName>", withExtension: "<imageExtension png/jpg/etc>")!
let expectedImage = NSImage(contentsOf: url)!.tiffRepresentation!
url = Bundle(for: AnyClass.self).url(forResource: "<NameOfDummyImageFile>", withExtension: "png")!
try? cells.images["My Image View"].screenshot().pngRepresentation.write(to: url)
let actualImage = NSImage(contentsOf: url)!.tiffRepresentation!
XCTAssert(actualImage.elementsEqual(expectedImage), "Images are not same.")
The above code works for me.. Hope this will work for you too

XCUIElementQuery.matching(identifier:) is not working for UIImageView

I'm trying to implement a very simple test, but I'm stuck with XCUIElementQuery.matching(identifier:) method. I think querying UIImageViews is not working as expected, but not sure why.
I have these two settings set for views:
Label:
UIImageView:
And I have this test:
func testRecording() {
XCTAssertEqual(app.staticTexts.matching(identifier: "label").count, 2)
XCTAssertEqual(app.images.matching(identifier: "accept").count, 1)
}
where I'm querying for these two views (Label with id label and UIImageView with id accept). From here: app is simply defined as class property like this: let app = XCUIApplication().
So, this is what screen looks like:
This means that this test should pass since there are two staticTexts with id label and one image with id accept on screen. staticTexts are being successfully queried, but it is failing when matching(identifier:) tries to query image with id accept:
I tried to query with many things, like:
app.images.
app.tables.
app.tables.images.
app.tables.cells.images.
app.buttons. (also marked as Button in Traits part of the Accessibility settings)
app.staticTexts. (also marked as Static Text in Traits part of the Accessibility settings)
but no luck... Is there anything that I'm doing wrong here, or missing something?
OK, since I'm in the QA team, I haven't looked much to the dev code. But when I did, I found the answer.
UIImageView that is used for displaying check mark is never being used from .xib file, but instead is always allocated a new instance like this:
indicatorView = UIImageView(image: #imageLiteral(resourceName: "arrow_marked_ok_small"))
meaning that new accessibility options are set with initializer call, so that old UIImageView instance that has accessibility options from .xib file I posted in first two images is being overridden.

swift, How to get currently displayed image file name from UIImageView [duplicate]

This question already has answers here:
UIImageView - How to get the file name of the image assigned?
(17 answers)
Closed 4 years ago.
I want to get the image file name which is currently displayed at UIImageView. I tried to get it as follow:
let currentImage = alien.image // !alien is my image view
println(currentImage?.description)
but it prints:
Optional("<UIImage: 0x7fa61944c3d0>")
You can't do this. Neither in swift nor objective-c.
The thing to do is to store the data you want to retrieve. That is... store the name somewhere and use that to load the image. Not the other way around.
So create a property something like imageName and then use that to load the image.
As a work around, for images that I need to reference at a later time, I use the restoration ID to store the image name.
I used restoration ID in this way so that I could connect multiple buttons to the same #IBAction and identify them based on the image name stored in the restoration ID and run logic about what I want to display or hide.
There might be better ways but this worked in a pinch.
I put the image name in as the restoration ID.
Here is where I designate the file for the image..
And I just copy that and put it in as the restoration ID.
(note: that is not what this was intended to be used for as it is really meant for customizing state reference but if that is not relevant to the purpose of your view, then it should work fine.)
Referenced in code when the button is selected.
//Connected to several onboarding buttons.
#IBAction func onBoardingButton(sender: UIButton) {
println(sender.restorationIdentifier)
}
RID printed out.
You can also tag your images and keep the reference to those images via the tag.
And the reference is just as easy.
#IBAction func onBoardingButton(sender: UIButton) {
println(sender.restorationIdentifier!)
println(sender.tag)
}
While it doesn't seem like we can discern what file was used to fill the imageview (that I know of and based on a little looking around myself) attaching hard references to a view (image, button, etc..) allows me to make the connection code side and figure out which image (or in my case button) is being used.

Are Images assigned in a xib cached?

If I assign an image to a UIImage view in a xib, is that image cached so that if I access the image using UIImage imageNamed: I am getting cached Image data?
I'm using iOS 5.1
UIImage imageNamed: does its own cacheing of any images you use. The first time you use it for a given image, it'll populate the cache, and subsequently it'll use the cached version.
UIImageView in Interface Builder takes a string to tell it what image to use. It appears that the object that is actually encoded in the Xib to represent the image is a private class called UIImageNibPlaceholder, which contains a private NSString variable called runtimeResourceName. It's this class that implements the initWithCoder: method which is used when the system is loading objects from a xib.
So, the question is, inside UIImageNibPlaceholder's initWithCoder:, does it use the imageNamed: function of UIImage? I think it's reasonable to assume that it does, since the thing stored in the xib is the string runtimeResourceName, and the system is turning that string into an actual image when loading the xib.
This post on the Apple developer forums seems to clarify the point (under NDA so I can't copy it here). I couldn't find any publicly accessible information on the subject.

Is there a way to inspect a view loaded via nib to find the resource names of images in the imageViews?

Looking for easy way to support retina displays. It occurred to me that if I could look through a nib-loaded view and get the names of all the image resources used there, I could check if they have a corresponding retina image and load it (if it's a retina device.)
I know how to iterate through subviews after it's loaded, but I don't know how (or if you can) get the resource name set in Interface Builder. I'm trying to avoid having to set all the image names in code.
What I'd like to do (in pseudo code):
for subView in self.view.subviews:
if subView is UIImageView:
resourceName = (UIImageView *)subView.imageName
if retinaResourceFileExists(resourceName) and isRetinaDisplay:
(UIImageView *)subView.image = retinaImage(resourceName)
(Bonus: Maybe there is a way to iterate through IBOutlet variables, but I doubt it?)
use [UIImage imageNamed:#"Foo"]; and the device will load the #2x image automatically.
Interface Builder loads the retina image automatically, too.

Resources