FILE-ACCESS Reading images previously written to NSDocumentDirectory FAILS - ios

Having recently downloaded and installed XCode 4.3 from the App Store, I find a serious and unexpected problem when reading image-files (large JPEG files) previously stored in the application User Documents. The issue is as follows:
(i) The files derive from the user's photo-library and the UIcropped original image ( UIImagePickerControllerOriginalImage) is correctly stored to User Documents. Inspection of the User Documents folder shows the image file correctly stored. Copying this file to my user-account creates a copy that can be loaded (for example) into the Preview application or else iPhoto. The expected image is loaded by Preview and iPhoto and can be seen to be visually correct.
(ii) On attempting to read the stored file with the standard method
UIImage * image = [ UIImage imageWithContentsOfFile: file ]
method (where file is the full path-name of the stored file) the image returned is nil. nil is also returned on attempting an NSData load via
NSData * data = [ NSData dataWithContentsOfFile: file options:
NSDataReadingMappedIfSafe error: & error ];
In this case the full NSError * error object is reported as follows:
CODE= 260, DOMAIN= NSCocoaErrorDomain,
USERINFO =
{ NSFilePath = "<User Documents>/<filename>.jpeg";
NSUnderlyingError = "Error Domain=NSPOSIXErrorDomain
Code=2 \"The operation couldn't be completed. No such file or directory\"";
}
(iii) Examining the copied file in Finder shows that the "Kind" of the previousl;y written image-file is now "Document" wheras previously it was (as expected) "JPEG Image". This is the ONLY evident problem with the file.
(iv) Replacing the previous written file with an externally created JPEG image file WITH EXACTLY THE SAME NAME results in a successful loading of the file via [ UIImage imageWithContentsOfFile: file ]!
THIS LOOKS, THEREFORE, TO BE A PERMISSIONS PROBLEM RATHER THAN A JPEG-DATA PROBLEM. New with XCode 4.3 installation is the Kind= "Document" replacing the previous (and working) Kind = "JPEG Image". CAN ANYONE PLEASE THROW LIGHT ON THIS MATTER AND IF POSSIBLE ADVISE A SOLUTION? The matter is urgent & frustrating for me as it breaks a PDF design tool under urgent development!
Best Wishes,
Negative Entropy

Can you debug and "po file" from the console? I've not seen a permission problem before, so I suspect the path. Also, we have seen issues with case sensitivity (iOS is case sensitive, whereas your Simulator may not be). Need to see the full path variable contents.

Related

What is `NSLocalizedFailureErrorKey` for?

Among the well-documented strings NSLocalizedDescriptionKey, NSLocalizedFailureReasonErrorKey, NSLocalizedRecoveryOptionsErrorKey, and NSLocalizedRecoverySuggestionErrorKey there is also NSLocalizedFailureErrorKey, which lacks any kind of description in documentation. What is it for?
From the header:
FOUNDATION_EXPORT NSErrorUserInfoKey const NSLocalizedFailureErrorKey API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));
// NSString
A complete sentence (or more) describing what failed. Setting a value for this key in userInfo dictionary of errors received from framework APIs is a good way to customize and fine tune the localizedDescription of an NSError.
As an example, for Foundation error code NSFileWriteOutOfSpaceError, setting the value of this key to "The image library could not be saved." will allow the localizedDescription of the error to come out as "The image library could not be saved. The volume Macintosh HD is out of space." rather than the default (say) “You can't save the file ImgDatabaseV2 because the volume Macintosh HD is out of space."

How to save breakpoints in Centura 6 Team Developer SQL/Windows

How can I save breakpoints in Gupta 6? When i refresh libraries after inserting some code into another .apt, my breakpoints in main program are lost. Is there any trick how to prevent from it?
Breakpoints will be saved if you save the file as TYPE binary ( i.e. save as file type = 'Normal' ) , not if saved as Text ( i.e. file type = 'TEXT' or 'INDENTED TEXT' ). This is regardless of what file extension you have . p.s. only save as binary if you're in debug mode. Otherwise difficult to fix if code becomes corrupt. If saved as Text - much easier to fix.

UIImage imageWithContentsOfFile: not working on real device

I'm creating a tableView which contains the images from gallery picked by the user, then I take the selected imagePath to place it on an UIImageView.
To set an iOS gallery image in a UIImageView,
I'm using:
NSString *imgPath = #"/var/mobile/Media/DCIM/105APPLE/IMG_5903.JPG";//Hardcoded path just for test, image actually exists on iOS device
self.imgViewContainer.image = [UIImage imageWithContentsOfFile: imgPath];
This code which works on Simulator.
I tested on a real device and I noticed that the UIImageView is empty after execute the above code.
Is there a way to achieve this using a real device?
Due to app sandboxing, your app does not have permission to view the contents of /var/mobile/Media (or really any subdirectory of /var/). Consider the code below:
do {
let fileList = try FileManager.default.contentsOfDirectory(atPath: "/var/mobile/Media/DCIM/")
} catch {
print(error)
}
contentsOfDirectory(atPath:) with throw an error with these details:
Error Domain=NSCocoaErrorDomain Code=257 "The file “DCIM” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/var/mobile/Media/DCIM/, NSUserStringVariant=(
Folder
), NSUnderlyingError=0x170045700 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
This example is in Swift, but the equivalent Objective-C code would have the same error.
There is no way around this (unless your are using a jailbroken device running your application as the root user). Use UIImagePickerController to ask the user for an image.

iOS Adding Initial Core Data file using UIManagedDocument, NOT appdelegate

I am trying to load an initial database into my app so my core data db is not empty upon install. I'm now using this code:
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%#_InitialData", SQL_DATABASE_NAME] ofType:#"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
(from http://code.google.com/p/coredatalibrary/wiki/LoadingInitialData)
to try and load an initial sqlite file for my core data to use. It isn't working and my program differs from the type used in that link in a few ways.
It appears the tutorial uses a file created to "use core data", which I am not. I just didn't happen to learn it that way (watched the stanford cs193p videos) and instead I'm using UIManagedDocument and performing this code in my top view controller. Because of this, I've run into a few problems.
I loaded up my app to create the initial data base so I could save the file to use for initial values. Upon doing so, I found that the way things are saved are different from in the tutorial. For example, if my url for my UIManagedDocument is .../Documents/Test , then my database file is .../Documents/Test/Store Content/persistentStore, where "persistentStore" is the database file. For one thing, a "Store Content" directory has been added. In addition, the sqlite file is named persistentStore and has no file extension. When I open the file it says
SQLite format 3���# �����������������������������������������������������������������-‚%
on the top though (I'm not familiar with SQLite or any db format for that matter but I assume this means it is an sqlite file).
I save this "persistentStore" file to use to load into my app using the code above. Upon doing so, I found that copyItemAtPath:toPath:error: will not copy as I expect. For example, if the storePath is .../Documents/Test , then my sqlite file that I'm copying over becomes renamed to Test.sqlite and is located at .../Documents/ instead of copying my file to a location of .../Documents/Test/.
Because of this, when I try to open the UIManagedDocument at that url (.../Documents/Test) I get this error
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason:
'UIManagedDocument can only read documents that are file packages'
I've tried creating a directory to mimic the one created by core data before copying over my intial data (that is, I create the directories to have a path of .../Documents/Test/Store Content/ and then copy my initial data to be in the "Store Content" folder with a name of persistentStore) but that also doesn't work. UIManagedDocument can't open the document.
So how can I load in initial values to my core data db without having a project that is set to "use core data"? I have the (presumably) sqlite file with the initial data (when I open it and skim it it appears to have my initial values), so I just need to know how to copy it over properly so that I can still used UIManagedDocument to open the document and save via the UIManagedObjectContext.
It turns out my way of recreating the path created by core data worked. That is, creating the directories of .../Test/Store Content/ and copying the file as "persistentStore". My error was a small one. It was suppose to be StoreContent instead of "Store Content"; I added a space...

iOS - UIImage imageNamed: returns null on device

[UIImage imageNamed:filename]
This method returns null only on the device.
I know it's known problem and it's usually due to the fact that simulator is case insensitive.
I have tried solutions proposed here: UIImage imageNamed returns nil
But nothing worked out for me.
The case is simple: I have 4 files named:Bar#2x~ipad.png, Bar#2x~iphone.png, Bar~ipad.png, Bar~iphone.png.
All of them are in project with target checkbox checked.
NSLog(#"%#",[UIImage imageNamed:#"Bar"]);
That line of code gives me null for device and I really have no idea what I'm doing wrong right now.
I did have such a problem recently too.
After playing with filenames and paths sometimes it helps when you clean and rebuild your project.
I found myself in the same situation recently.
The solution in my case was adding the extension to the file name.
[UIImage imageNamed:#"Bar.png"]
Completely clean your build and redo it:
delete the app from the device
option-clean the whole build directory in Xcode (⌘-Shift-K)
quit xcode
delete ~/Library/Developer/Xcode/DerivedData
restart xcode, build and run
This just happened to me, and to discover was very tough: I had one image which where nil just on device
logoWhite.png
my code:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"LogoWhite"] forBarMetrics:UIBarMetricsDefault];
After a while of debugging, I noticed that the name of the image is beginning with capital case letter. Obviously this doesn't matter on OSX with a ignore case file system. iOs file system isn't, so the image worked on the simulator but not on the device.
I bet that all the solutions about cleaning derived data and rebuild did randomly end with renaming the image, and this would do the trick as well. Just posting here for future reference :)
I encountered this issue and just fixed it. I listed the solution below as a reference.
I have several images, and use [UIImage imageNamed:filePath] to show them. All of images displayed well except 1 on simulator/device, but all of them can be seen on OS X. For that image, [UIImage imageNamed] always return null.
After few minutes' investigation, I found that the image cause problem is far big in file size: 4.1M. Others are all around 800kb. They have nearly same size in dimension.
Then I try to open it in image editor, then re-save it. After this, the size dropped to 800k. problem solved.
The reasons I guess,
[UIImage imageNamed:filePath] has a max file size limit? (low possibility, but need to check official document)
the image itself has some error. But OS X has better tolerance than iOS. so iOS cannot read and return null. This issue is like OS X can play more types of video files than iOS since it support more codecs.
so if you encounter this issue in the future, take a few seconds look at the file size. Hope help.
This is an odd problem, which I hadn't seen until this week.
Below are my findings, and a workaround to your problem.
In my iPhone app, I download an image and store it locally, and this had always worked fine.
But now when I run the same code, it was suddenly failing to create a UIImage out of it using the imageNamed function, and now it was returning nil.
Three notes though:
This exact code did work before, using the same source code and .png image files. I'm not sure if my copy of XCode 6.x or iOS 8.x quietly updated itself in the meantime.
The code continues to work okay (with the same image file) on the iPhone simulator. It just doesn't work on a real device.
Take a look at the code below. When UIImage:imageNamed failed, I ran some code to check if the file actually existed.. and it did. Then I loaded the binary data from the file using NSData:contentsAtPath (which also proves that the file exists and was in the right folder), then created a UIImage out of that, and it worked fine.
Huh ?!
UIImage* img = [UIImage imageNamed:backgroundImageFilename];
if (img != nil)
{
// The image loaded fine (this always worked before). Job done.
// We'll set our UIImageView "imgBackgroundView" to contain this image.
self.imgBackgroundView.image = img;
}
else
{
// We were unable to load the image file for some reason.
// Let's investigate why.
// First, I checked whether the image was actually on the device, and this returned TRUE...
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:backgroundImageFilename];
if (fileExists)
NSLog(#"Image file does exist.");
else
NSLog(#"Image file does not exist.");
// Next, I attempted to just load the bytes in the file, and amazingly, this also worked fine...
NSData *data = [[NSFileManager defaultManager] contentsAtPath:backgroundImageFilename];
if (data != nil)
{
// ..and then I COULD actually create a UIImage out of it.
img = [UIImage imageWithData:data];
if (img != nil)
{
// We have managed to load the .png file, and can now
// set our UIImageView "imgBackgroundView" to contain this image.
self.imgBackgroundView.image = img;
}
}
}
As I said, this code does provide a workaround for this problem, but it's very odd that it's suddenly started happening.
And, I should say, I did try the other suggestions in this thread, cleaning the project, removing the DerivedData, completely removing the app from the device, and so on, but they didn't make any difference.
I would be interested in knowing if anyone else hits this issue, and finds that my code sample works for them.
Update
I'm an idiot.
I'm not sure if the UIImage:imageNamed function has changed or something (and if so, why it continues to work okay on the iPhone 8.1 Simulator), but I found the following one line does work okay:
UIImage* img = [[UIImage alloc] initWithContentsOfFile:backgroundImageFilename];
So it seems as though you should use this function for loading images which aren't a part of your app's bundle.
I also have same issue then : XCode - Build Phases - Copy Bundle Resources -{see image is available or not}- add{image} - clean - delete app - Run .
I would like to add one more important point to all the above solutions
Make sure you add your image resource to right target
By mistake if Developer mess-up link with resource and target then conditions arise.
if you have multiple target then double check the resource are set to correct target.
Attached screenshot example in case of resource link between multiple targets.

Resources