iPad saving audio save to local MusicDirectory - ios

iOS 8.2
iPad a1474
inside app on IPAD, my code is
var dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
user records voice and it saves to
Optional(file:///var/mobile/Containers/Data/Application/2B2028C4-8E7D-4D7F-9FAF-EB843F506A5E/Documents/audio-2015-01-25-144545.m4a)
in Itunes/App,
have tried
MusicDirectory and SharedPublicDirectory
with either of
LocalDomainMask or DocumentDirectory
none work with error
The operation couldn’t be completed. (OSStatus error 2003334207.)
fatal error: unexpectedly found nil while unwrapping an Optional value
so what gives?
why can't app save to local MusicDirectory on the iPad??? there is nothing in the docs to indicate that this is protected area on the iPad.
no issues with iTunes or OSX, this is an iOS issue.

Under iOS8, the path that you have saved won't be the same across launches. The id you see "410AB24E-5FB0-4401-AC59-3C03D676E951" will change with each launch.
The workaround is to save the filename and not the complete path, and to recreate the URL or complete path, by getting the path to the Documents (or tmp) folder and appending the filename to it.

Related

AVAudioRecorder/AVAudioPlayer not able to open previously saved file

I can successfully record audio using AVAudioRecorder. I can successfully play this recording using AVAudioPlayer.
This is saved to the documents folder:
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
However, when i try to re-open this file (to either record over it or play it back) i am unable to do so. I get recording state or player state to return false.
An example of the file name/URL:
file:///var/mobile/Containers/Data/Application/30025787-C4F5-4F23-A345-C38EE44A180B/Documents/E678B939-730D-40D8-84EC-DE79FE4BDE3D.m4a
Note that i try to re-open the file like this:
self.audioRecorder = try AVAudioRecorder(url: self.recordedFileURL!, settings: settings)
self.audioRecorder.delegate = self
self.audioRecorder.isMeteringEnabled = true
let prepared = self.audioRecorder.prepareToRecord()
print("prepared to record = \(prepared)") // this returns FALSE when i am trying to re-open. But returns TRUE when i record for the first time.
When i try to open the file with the AVAudioPlayer i get error:
The operation couldn’t be completed. (OSStatus error 2003334207.)
The code to open the file using the saved URL is this:
if (self.recordedFileURL != nil) {
do {
self.audioPlayer = try AVAudioPlayer(contentsOf: self.recordedFileURL!)
self.audioPlayer.delegate = self
self.audioPlayer.volume = 1.0
self.audioPlayer.prepareToPlay()
}
catch let error {
print("Play audio error: " + error.localizedDescription)
}
}
* Updated *
I am beginning to think the file is actually not saved in the documents folder. I see this error in the output window:
fatal error: unexpectedly found nil while unwrapping an Optional value
2016-11-07 09:38:28.177535 fatal error: unexpectedly found nil while unwrapping an Optional value
How to verify this file exists in the documents folder?
* Updated *
I suspect I am saving the file to a temporary location. I will need to investigate in this direction once I get home. Here is a reference.
* updated 2 *
I found a better more precise reference here.
* RESOLVED *
I believe there were a couple (2) issues.
1) I made sure that I'm not using the path name of a file that already exists. If I use an existing path (which is the path to a recorded audio) to initialize the Recorder, it will override whatever audio was recorded. I had to make sure to use a separate/unique path for any new recording.
2) I had to ensure that I am working with the right URL paths. I found out that I wasn't consistent with this. In short, use the absolute string path, and use that consistently everywhere (reading & reading).

Unable to read data from Realm file

I want to use realm file with implicit data in my app (In separate project I filled it with data, then made copy of it. Model object is same in both apps).
On simulator, everything is just fine. But when I run app on iPhone, Xcode throws me error.
let path = (NSBundle.mainBundle().pathForResource("testLevel", ofType: "realm"))!
let config = Realm.Configuration(path: path)
let realm = try! Realm(configuration: config) // also tried try! Realm(path: path)
When I print path to .realm file, everything's fine - no nil -
Dont know how to handle it, any ideas? (iOS9)
Error:
fatal error: 'try!' expression unexpectedly raised an error: Error
Domain=io.realm Code=2 "Operation not permitted" UserInfo={Error
Code=2,
NSFilePath=/var/containers/Bundle/Application/7DE151B5-42EE-45C6-8245-B57683EA64D8/sneakers.app/testLevel.realm,
NSLocalizedDescription=Operation not permitted}: file
/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-703.0.18.1/src/swift/stdlib/public/core/ErrorType.swift,
line 54
The Resources folder of your app is read-only, so you can't directly open a writeable Realm file from there.
You'll need to copy it to a directory in which your app has write access (e.g the 'Documents' or 'Application Support' directories) and then try and open it from there. :)

Unable to open a realm at path

I am trying to use a bundled realm file without success. I know that my realm file was copied successfully to my application’s Directory but I ca not read it.
fatal error: 'try!' expression unexpectedly raised an error: "Unable
to open a realm at path
'/Users/…/Library/Developer/CoreSimulator/Devices/…/data/Containers/Data/Application/…/Documents/default-v1.realm'.
Please use a path where your app has read-write permissions."
func fullPathToFileInAppDocumentsDir(fileName: String) -> String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,NSSearchPathDomainMask.UserDomainMask,true)
let documentsDirectory = paths[0] as NSString
let fullPathToTheFile = documentsDirectory.stringByAppendingPathComponent(fileName)
return fullPathToTheFile
}
In didFinishLaunchingWithOptions:
let fileInDocuments = fullPathToFileInAppDocumentsDir("default-v1.realm")
if !NSFileManager.defaultManager().fileExistsAtPath(fileInDocuments) {
let bundle = NSBundle.mainBundle()
let fileInBundle = bundle.pathForResource("default-v1", ofType: "realm")
let fileManager = NSFileManager.defaultManager()
do {
try fileManager.copyItemAtPath(fileInBundle!, toPath: fileInDocuments)
} catch { print(error) }
}
And setting the configuration used for the default Realm:
var config = Realm.Configuration()
config.path = fileInDocuments
Realm.Configuration.defaultConfiguration = config
let realm = try! Realm(configuration: config) // It fails here!!! :-)
As the documentation suggests, I have tried as well to open it directly from the bundle path by setting readOnly to true on the Realm.Configuration object. I am not sure if this is something related to Realm or if I am overlooking something with the file system…. I have also tried to store the file in the Library folder.
Realm 0.97.0
Xcode Version 7.1.1
I tried to open the realm file using Realm's browser app and the file does not open anymore. It has now new permissions: Write only (Dropbox). So, I decided to change the file permission back to read/write using file manager’s setAttributes method. Here is how I did it:
// rw rw r : Attention for octal-literal in Swift "0o".
let permission = NSNumber(short: 0o664)
do {
try fileManager.setAttributes([NSFilePosixPermissions:permission], ofItemAtPath: fileInDocuments)
} catch { print(error) }
The realm file can now be open at this path.
That exception gets thrown whenever a low level I/O operation is denied permission to the file you've specified (You can check it out on Realm's GitHub account).
Even though everything seems correct in your sample code there, something must be set incorrectly with the file location (Whether it be the file path to your bundle's Realm file, or the destination path) to be causing that error.
A couple of things I can recommend trying out.
Through breakpoints/logging, manually double-check that both fileInDocuments and fileInBundle are being correctly created and are pointing at the locations you were expecting.
When running the app in the Simulator, use a tool like SimPholders to track down the Documents directory of your app on your computer, and visually ensure that the Realm file is being properly copied to where you're expecting.
If the Realm file is in the right place, you can also Realm's Browser app to try opening the Realm file to ensure that the file was copied correctly and still opens properly.
Try testing the code on a proper iOS device to see if the same error is occurring on the native system.
If all else fails, try doing some Realm operations with the default Realm (Which will simply deposit a default.realm file in your Documents directory), just to completely discount there isn't something wrong with your file system
Let me know how you go with that, and if you still can't work out the problem, we can keep looking. :)
This will occur if you have your realm file open in Realm Studio at same time you relaunch your app. Basically in this case Realm can't get write permissions if Studio already has them.
To add to the solution based on what I've discovered, make note of what error Realm reports when it throws the exception, as well as the type of Error that is passed.
As of writing, Realm documents their errors here:
https://realm.io/docs/objc/latest/api/Enums/RLMError.html
What this means is that you can find out if your Realm file has permissions problems and react to those based on Realm passing you a RLMErrorFilePermissionDenied. Or if the file doesn't exist with RLMErrorFileNotFound.
The tricky thing I'm finding is when you get a more generic RLMErrorFileAccess, but that's for another question on Stack Overflow...
I had the same issue and tried too many ways to fix it. The easiest way to fix this problem is manually creation of the folder XCode cannot reach '/Users/…/Library/Developer/CoreSimulator/Devices/…/data/Containers/Data/Application/…/Documents/...' as explained at https://docs.realm.io/sync/using-synced-realms/errors#unable-to-open-realm-at-path-less-than-path-greater-than-make_dir-failed-no-such-file-or-directory
Once you created this folder and run the project, XCode creates the Realm files inside this folder automatically.

Can I save files/folders in NSSearchPathDirectory.ApplicationDirectory? NSSearchPathDirectory.DocumentDirectory is not ideal for me

iOS 8.4 | Swift 2.1
When I was tried to create a new folder in NSSearchPathDirectory.ApplicationDirectory, I followed with this error on device (in simulator it did worked, though):
code:
let docuPath:NSURL = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.ApplicationDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0])
ConstantsVO.imagePath = docuPath.URLByAppendingPathComponent("imagegallery")
if !NSFileManager.defaultManager().fileExistsAtPath(ConstantsVO.imagePath.path!)
{
do
{
try NSFileManager.defaultManager().createDirectoryAtPath(ConstantsVO.imagePath.path!, withIntermediateDirectories: true, attributes: nil)
}
catch let error as NSError
{
NSLog("\(error.localizedDescription)")
}
catch
{
print("general error - \(error)", terminator: "\n")
}
}
error
2015-11-02 10:53:21.114 Elmo[218:5055] You don’t have permission to
save the file “imagegallery” in the folder “Applications”. fatal error:
'try!' expression unexpectedly raised an error: Error
Domain=NSCocoaErrorDomain Code=4 "The file “imagegallery” doesn’t
exist."
UserInfo={NSURL=file:///var/mobile/Containers/Data/Application/48D90635-0D66-44C2-81CE-F67BAFDA819A/Applications/imagegallery,
NSFilePath=/var/mobile/Containers/Data/Application/48D90635-0D66-44C2-81CE-F67BAFDA819A/Applications/imagegallery,
NSUnderlyingError=0x16e7d540 {Error Domain=NSPOSIXErrorDomain Code=2
"No such file or directory"}}: file
/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-700.0.59/src/swift/stdlib/public/core/ErrorType.swift,
line 50
However, using NSSearchPathDirectory.DocumentDirectory did worked for me and worked expectedly. But in my application, I've feature to share/import through iTunes, so I have the "Application supports iTunes file sharing" TRUE in my info.plist - this exposed NSSearchPathDirectory.DocumentDirectory in iTunes. I don't want the files/folders that I'm saving through my app to be expose to the user in iTunes. Then where should I save the files/folders yet can able to use file sharing through iTunes by exposing NSSearchPathDirectory.DocumentDirectory?
I found the answer from this post is helpful:
Path directory usable in iOS
As far as I know only these are usable on iOS:
NSDocumentDirectory is Documents/ (persistent, backed up, may
be visible in iTunes) NSLibraryDirectory is Library/
(persistent, backed up, not visibe to the user) NSCachesDirectory is
Library/Caches/ (not backed up, may be cleared by system)
Now after I'm using NSSearchPathDirectory.LibraryDirectory the I'm having no NSFileManager error on device nor the directories/files I'm storing inside NSSearchPathDirectory.LibraryDirectory are exposed to the users in iTunes sharing tab.
Great!

AVAudioplayer not working after project rebuild

I have an audio player that plays local files.
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]
It works fine. However if I click xcode run button to rebuild the app, the player is not working. It gives me Error
Error Domain=NSOSStatusErrorDomain Code=2003334207 "The operation couldn't be completed. (NSOSStatus error 2003334207.)"
The url is absolutely the same. I checked the file. It is where it says it is and it is not corrupt or anything.
Edit:
[[NSFileManager defaultManager] fileExistsAtPath:url.path]
returns false but if the file is there what this means is that I don't have access to it?
Likely, with iOS8, the path that you have saved won't be valid across launches.
The solution is to save the filename and not the complete path, and to recreate the URL or complete path, by getting the path to the Documents (or tmp) folder and appending the filename to it.

Resources