NSRangeException with PHFetchResult - ios

I am developing an iOS App that fetches videos from the Photo gallery and it always worked. I just tested the app on a different device (this is not the first on which I test) and it crashes while I use the retrieved data and I don't understand why...
Here is my code :
self.videosAssets = PHAsset.fetchAssetsWithMediaType(.Video, options: nil)
if self.videosAssets != nil {
for i in 0..<self.videosAssets!.count {
if let video = self.videosAssets!.objectAtIndex(i) as? PHAsset {
self.videos.append(Video(asset: video))
}
}
}
It fetches 221 videos but it crashes when i == 59.
Here is the error I get :
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray'

self.videosAssets = PHAsset.fetchAssetsWithMediaType(.Video, options: nil)
if let videoAssets = self.videosAssets {
videoAssets.forEach { video in
if video as? PHAsset { self.videos.append(Video(asset: video)) }
}
}

After testing the Video constructor, it was the problem. For some reason, when I call let resources = PHAssetResource.assetResourcesForAsset(asset), it returns me an empty array and this is where the app was crashing.
Sorry for this useless post, maybe it will help someone...

Related

iOS WebRTC Local Media NSInvalidArgumentException [RTCI420Frame nativeHandle]

I am trying to create a local media stream in my iOS webRTC app. See code below
let localStream = pcFactory.mediaStream(withLabel: "ARDAMS")!
let audio = pcFactory.audioTrack(withID: "ARDAMSa0")
localStream.addAudioTrack(audio!)
var device: AVCaptureDevice?
for captureDevice in AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo){
if let captureDevice = captureDevice as? AVCaptureDevice{
if captureDevice.position == AVCaptureDevicePosition.front{
device = captureDevice
}
}
}
if let device = device{
let capture = RTCVideoCapturer(deviceName: device.localizedName)
let videoSource = pcFactory.videoSource(with: capture, constraints: nil)
localVideoTrack = pcFactory.videoTrack(withID: "ARDAMSv0", source: videoSource)
localStream.addVideoTrack(localVideoTrack)
}
self.peerConnection?.add(localStream)
localVideoTrack?.add(localVideoView)
Everything works, but when after I add the localVideoView to the localVideoTrack I get an error:
-[RTCI420Frame nativeHandle]: unrecognized selector sent to instance 0x170010620
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RTCI420Frame nativeHandle]: unrecognized selector sent to instance 0x170010620'
All of the code is running on the main thread and the app has the appropriate permissions and plist keys. When I walk through the code line by line using the debugger everything seems to be running correctly. This code was taken from the Obj-C AppRTC demo, it has just been converted to swift. I can't seem to find the difference between my swift project that crashes and the working AppRTC project. Any idea what I am doing wrong? I am testing on a 64 bit device. Thanks!

'PFObject values may not have class: NSConcreteValue'

App keeps crashing on this Method - trying to simply pin a Parse object to the local data store as outlined in the docs Parse docs:
func saveToBackground(title:String, description:String, coords:CLLocationCoordinate2D, image:UIImage, objectId:String, dateFound:String){
let imageData = image.jpeg(.low)
let imageFile = PFFile(name: "image.png", data: imageData!)
let foundObject = PFObject(className: "FoundObjects")
foundObject["title"] = title
foundObject["description"] = description
foundObject["coordinates"] = coords
foundObject["image"] = imageFile
foundObject["objectId"] = objectId
foundObject["dateFound"] = dateFound
foundObject.pinInBackground()
}
error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'PFObject values may not have class: NSConcreteValue'
Any ideas anyone?
At least one of your values is an NSConcreteValue class, which can't be stored on a PFObject. Figure out which line is causing the issue by setting a breakpoint and stepping through, and make sure to cast that value to the expected class. Or you could cast all of these to their expected class, cover your bases.
Edit: As pointed out by MartynE23, the issue was actually the CLLocationCoordinate2D, which must be converted to a PFGeoPoint to add to a Parse Object

Video upload from iPhone device fails but works on Simulator perfectly ERROR:'Cannot read file'

I am trying to upload a video from iPhone device as:
var uploadTask = self.session?.uploadTaskWithRequest(request, fromFile:NSURL(string: assetFilePath.path)!)
This code works on simulator and gives a session task object which I can resume. But it does not work on iPhone device.
It fails as:
2015-05-19 18:36:44.718 myApp[327:24703] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot read file at file:///var/mobile/Media/DCIM/100APPLE/IMG_0144.mp4'
I tried to check if the video file has read access, but it returns false on iPhone:
fileManager.fileExistsAtPath(asset.path) // returns false
Anybody has encountered this before, or am I doing something wrong here?
Code which I am using to get the file path is :
let options = PHFetchOptions()
options.sortDescriptors = [
NSSortDescriptor(key: "creationDate", ascending: true)
]
currentVideofetch = PHAsset.fetchAssetsWithMediaType(.Video, options: options)
let asset = self.currentVideofetch.objectAtIndex(indexPath.row) as? PHAsset
var assetLength:NSNumber!
var assetFilePath:NSString!
if let checkdAsset = asset {
PHImageManager.defaultManager().requestImageDataForAsset(checkdAsset,options: nil) {
imageData,dataUTI,orientation,info in
assetLength = imageData.length as NSNumber
let assetFilePathUrl = info["PHImageFileURLKey"] as? NSURL
assetFilePath = assetFilePathUrl!.absoluteString!
println("Assets FilePath \(assetFilePath)") // returns file:///var/mobile/Media/DCIM/100APPLE/IMG_0144.mp4
}
}
After messing up with lot. This is classic permissions issue in iOS. Unfortunately I didn't get any straight answers to this. We had to copy file to our local directory of my App. After that everything is works like a charm.
But in case of large file I send copying file logic in background task.

NSAttributedString initialization throws NSRangeException

I wrote a simple extension to decode the html entities:
extension String {
func htmlDecode() -> String {
if let encodedData = self.data(using: String.Encoding.unicode) {
let attributedString = try! NSAttributedString(data: encodedData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.unicode], documentAttributes: nil)
return attributedString.string
}
return self
}
}
Now it throws an error on the line if let attributedString …:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 4 beyond bounds [0 .. 2]'
And self is not nil or something, just a String like this:
self = (String) "...über 25'000 Franken..."
Where is this strange NSArray-exception coming from?
A shot in the dark: do you ensure that the initialization happens on the main thread?
I had exactly the same problem. I noticed that in my case the exception occurs under reproducible conditions (animations in a UICollectionViewController), but I was unable to find the actual cause. My best guess is that it's a framework bug, so I'd too suggest you file a radar.
I ended up pre-rendering my HTML formatted strings into a cache (aka array) at a time where it works, and then load the NSAttributedStrings from it on demand.
Note though that this solution may not fit your use case, since I only have to deal with a limited amount of formatted strings at a time and hence know the expense of rendering them in advance.
In my case, this was happening because I was trying to instantiate a NSAttributedString from within a UICollectionViewCell that was in detached state (before it was inserted in the parent UICollectionView).
Seems like a bug, possibly related to how Swift strings handle characters differently than NSString.
I would file a radar.
DispatchQueue.main.async { let text = yourHtmlText.htmlDecode() }
I just run over this error with a different error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue unsignedIntegerValue]: unrecognized selector sent to instance 0x60000024b790'
And found a serious bug in this piece of code:
I was passing String.Encoding.unicode - a Swift value - to an Objective-C method that crashed the app. After using String.Encoding.unicode.rawValue the crash disappeared:
extension String {
func htmlDecode() -> String {
if let encodedData = self.data(using: String.Encoding.unicode) {
if let attributedString = try? NSAttributedString(data: encodedData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.unicode.rawValue], documentAttributes: nil) {
return attributedString.string
}
}
return self
}
}

exception com.apple.coreaudio.avfaudio reason: error -50

I have this message when i try to play an audio with a different pitch:
And i googled for that error with no succeed. If i set breakpoints it stops here:
I test printing all objects to see is anything is nit but i didnt found anything. The most misterious thing is that only happens in my iphone6+, in other phones i tested this out doesnt break. Then searched the project where i looked into to add this sound effects which is this:
https://github.com/atikur/Pitch-Perfect
And if you run it it works, until you change...
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, error: &error)
To:
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: &error)
And then boom (ONLY IN REAL DEVICE ATTACHED TO XCODE, it works in the simulator):
2015-03-21 11:56:13.311 Pitch Perfect[1237:607678] 11:56:13.311 ERROR: [0x10320c000] AVAudioFile.mm:496: -[AVAudioFile readIntoBuffer:frameCount:error:]: error -50
2015-03-21 11:56:13.313 Pitch Perfect[1237:607678] * Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -50'
* First throw call stack:
(0x18687a530 0x1978040e4 0x18687a3f0 0x1851ea6c0 0x185232d38 0x1852130f8 0x185212ccc 0x100584fd4 0x100584f94 0x10058fdb8 0x1005882c4 0x1005925d4 0x100592208 0x198037dc8 0x198037d24 0x198034ef8)
libc++abi.dylib: terminating with uncaught exception of type NSException
And the really really weird thing is this screenshot, for some reason after printing audioEngine, audioEngine.outputNode gets nil?
I had the same error... I had created a "sound.swift" class that my view controller would instantiate... I decided to simplify everything and focus on making the sound work. So I have put the following code in the view controller and it works:
//fetch recorded file
var pitchPlayer = AVAudioPlayerNode()
var timePitch = AVAudioUnitTimePitch()
let dirPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask,true)[0] as! String
var pathArray = [dirPath, String("son.wav")]
filePath = NSURL.fileURLWithPathComponents(pathArray)
audioFile = AVAudioFile(forReading: filePath.filePathURL, error: nil)
audioEngine = AVAudioEngine()
audioEngine.attachNode(pitchPlayer)
audioEngine.attachNode(timePitch)
//Create a session
var session=AVAudioSession.sharedInstance()
session.setCategory(AVAudioSessionCategoryPlayAndRecord,error:nil)
//output audio
session.overrideOutputAudioPort(AVAudioSessionPortOverride.Speaker, error: nil)
audioEngine.connect(pitchPlayer, to: timePitch, format: audioFile.processingFormat)
audioEngine.connect(timePitch, to: audioEngine.outputNode, format: audioFile.processingFormat)
pitchPlayer.scheduleFile(audioFile, atTime: nil, completionHandler: nil)
audioEngine.startAndReturnError(&audioError)
pitchPlayer.play()

Resources