(Swift) Can't retrieve paths for only video assets - swift

So I have a very simple call to get the path to a video file in Swift. Assuming the video is named "Video.mp4":
let path = NSBundle.mainBundle().pathForResource("Video", ofType: "mp4") // Returns nil
This returns nil, without exception. Same for using URLForResource().
The weird thing is that if have an image file that has been imported the same way (all assets are in the "Copy Bundle Resources" pane), it works perfectly:
let path = NSBundle.mainBundle().pathForResource("Image", ofType: "png") // Returns the correct path
Anybody have hunches on what might be causing this?
Thanks!

I had the same problem too. I finaly solved the problem.
Switch iOS Deployment Target to iOS 8
Run the app it works!!!
Switch iOS Deployment Target back to iOS 9
Run the app it works again!!!
A weird problem and a solution :))
I hope it helps.

Related

How play music in SceneKit

I tried to play music in my SceneKit game, but it crashes without a reason.
So I try to add this 3 lines of code in the standard Apple game template (at the end of viewDidLoad):
let music = SCNAudioSource(fileNamed: "Music.mp3")
let action = SCNAction.playAudio(music!, waitForCompletion: false)
ship.runAction(action)
and, at runtime, Xcode show me this message:
com.apple.scenekit.scnview-renderer (8): breakpoint 1.2
Where is my mistake?
I tried to compile and run my code in two different Mac: on my MacBookPro Retina it runs ok with the sound, in my iMac 21,5 it crashes.
So, my code is correct, probably I will fill a radar to Apple.
Note that both Macs are installed with OS Mojave in beta (same version) and also Xcode used is the Beta.
You have to put the audio file into an SCNAssets catalog (with .scnassets extension), like the art.scnassets catalog in the template. Then play the music like that:
if let source = SCNAudioSource(fileNamed: "art.scnassets/Music.mp3") {
let action = SCNAction.playAudio(source, waitForCompletion: false)
ship.runAction(action)
} else {
print("cannot find file")
}
I think you are looking for something like this...
ship.runAction(SKAction.playSoundFileNamed("Music.mp3",waitForCompletion:false));

Do I need to manually write code to initialize UI control which is dragged and dropped from InterfaceBuilder?

I'm a newbie.
I'm using Xcode 9.4 under macOS 10.13.5 and I'm writing a SingleViewApplication targeting iOS 11.4 with Swift 4.1.
I drag and drop a WkWebView to Main.storyboard and then made an referencing-outlet to my ViewController.swift and it's always nil.
Below is the screenshot.
By the way, my application in my simulator is always black.
I don't know why.
I think that you have 2 major problems in this code.
First, did you bind the webView to the code properlly? if not, (and because your a newbe in swift) i recommend you to watch this video below to understand how to make connection between your storyBoard and the code.
https://www.youtube.com/watch?v=rnF_OkhzS-o
Second, you're checking if webView is nil. it will allways be nil because you don't applay anything to it.
get rid of this question and just applay the URL to it.
edit:
here is an example for how it supposed to look like:
let url = URL(string: "https://stackoverflow.com")
let request = URLRequest(url: url!)
webView.load(request)
webView.navigationDelegate = self

Swift 4: CUICatalog: Invalid asset name supplied: '(null)' when using AVPlayerViewController Only

I'm trying to play a local video file and keep getting the following log:
[framework] CUICatalog: Invalid asset name supplied: '(null)'
My video file is in the project directory and also in the main bundle resources. I've tried multiple versions of the syntax to play the video. Here's the code I have for now in a test project:
#IBAction func buttonAction(_ sender: Any) {
if let path = Bundle.main.path(forResource: "slipMovement", ofType:
"mp4") {
let video = AVPlayer(url: URL(fileURLWithPath: path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
present(videoPlayer, animated: true, completion: {
video.play()
})
}
}
When I use a AVplayer and PlayerLayer, I don't get the 'null' messages. It only happens when I use AVPlayerViewController.
I'm fairly new to programming, any help would be very much appreciated as I just can't find a working solution online.
I experienced this same problem when playing downloaded files from AWS S3.
I don't have an explanation for the meaning behind the error message.
But in my case it was because the file was not actually playable.
1. Make sure the path is correct.
I did not use Bundle.
I put the file under the Documents directory and I used FileManager to set the path:
let documentsUrl: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let localFileName: String = "recording.mp4"
let localFileUrl = documentsUrl.appendingPathComponent(localFileName)
print("Playing \(localFileUrl.absoluteString)")
That would print something like this:
file:///var/mobile/Containers/Data/Application/D8AF92BD-D736-4B86-9FF4-C60ABA6C741B/Documents/recording.mp4
2. Make sure the file is actually playable.
For this, I wanted to check what the file is actually like when it's stored on the device.
It turned out that file was "corrupted" (ex. copy/download interrupted), so it really wasn't playable.
Connect the iOS device to your Mac.
From Xcode, go to Window > Devices and Simulators
Look for your device from the Connected list on the left.
Look for your app from the Installed Apps list.
Click the gears on the bottom of the list.
Select Download Container..
Download the *.xcappdata to a local directory
Open the directory in Finder
Right-click on the *.xcappdata, then select Show Package Contents
It should show something like the image below
Check the file's properties and try to play it
3. Make sure the file format is actually supported by AVPlayer
To see the supported AVPlayer formats, use print(AVURLAsset.audiovisualTypes()).
Reference:
https://developer.apple.com/documentation/avfoundation/avurlasset/1386800-audiovisualtypes
Once the path, the file, and the format were all OK, and I was able to play it normally using AVPlayer and AVPlayerViewController.
let player = AVPlayer(url: localFileUrl)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}

AVPlayer can't load .mov file saved after re-running app via xcode

I have this app in which the main purpose is to record video using AVFoundation, and then saving the outputfile delegate.
On first any normal run the app could properly record and save the video, and I could load the resulting outputfile URL into Avplayer I have on the next viewcontroller.
The AVPlayer would play just fine normally if the Xcode is not re-run. What I mean with rerunning is tapping into the Command+R again or clicking on the Play button on xcode to rebuild re-run.
What happens when I run the app again is that I could still see the files and list them via print, but when I'm trying to access the recorded file the app would no longer play the video. It would seem that the video wasn't loaded properly or anything even if it had already been working earlier. After this happens I could still go on record new ones and play the newly recorded ones, but not the old files.
The old files before rebuild of app would just look like this on AVPlayer
Also the AVPlayer would successfully return .readyToPlay status on my observer.
I'm confused how should I go on fixing this one.
if let videoPreviewController = storyBoard.instantiateViewController(withIdentifier: "VideoPreviewController") as? VideoPreviewController {
let url = NSURL(fileURLWithPath: "file:///var/mobile/Containers/Data/Application/61E182ED-D490-4C7D-BAB7-C90D095C7E43/Documents/Thursday,%208%20June%202017%20at%201:47:51%20PM%20Philippine%20Standard%20Time.mov")
videoPreviewController.player = AVPlayer()
let playerItem = AVPlayerItem.init(url: url as URL)
videoPreviewController.player?.replaceCurrentItem(with: playerItem)
videoPreviewController.report = relationship
videoPreviewController.appointment = self.appointment
navigation.pushViewController(videoPreviewController, animated: true)
}
Your problem is this line:
let url = NSURL(fileURLWithPath: "file:///var/mobile/Containers/Data/Application/61E182ED-D490-4C7D-BAB7-C90D095C7E43/Documents/Thursday,%208%20June%202017%20at%201:47:51%20PM%20Philippine%20Standard%20Time.mov")
That path will change every time your restart your app -- you can't hard code it. You have to ask the OS for the path to your documents folder and append your filename to it.
let userDocumentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileName = "Thursday,%208%20June%202017%20at%201:47:51%20PM%20Philippine%20Standard%20Time.mov"
let movieURL = userDocumentsURL.appendingPathComponent(fileName)
And by the way, that's probably how you saved the file in the first place... get the path, append your filename and save it.

Error: "No Such Module 'AVFoundation' " [duplicate]

Can the Apple Watch use AVFoundation? More specifically, can AVAudioPlayer and AVAudioRecorder work?
I am trying to make an app that lets you record a sound to the Apple Watch and have it play it back using the audioplayer. Thanks
UPDATE 11/28/15
This answer applies to WatchKit and WatchOS 1.x. Though I have not tested myself, WatchOS 2.x offers different support, including hardware. I can confirm that as of XCode 7.x, the compiler behaves correctly and WatchKit 1.x extensions with calls to AVFoundation won't build.
For WatchOS 1.x and XCode up to 6.x
Despite the fact that AVAudioRecorder and AVAudioPlayer both work in Simulator Apple Watch, they don't actually work on an actual device! I had opened a bug with Apple back on 5/5/15 (once I got to test an App I had written on my actual watch.) My app (a wrist audio recorded) indeed worked beautifully on Simulator. Yet on the actual watch, it would install and run, but the AVAudioRecorder "record" message would simply never toggle into "recording". Interestingly, the code does not throw any exceptions anywhere. It simply does not record!
I received a reply to my Apple Bug today 5/28/15 that "there are no plans to address this" based on "AVFoundation isn't supported on the watch." No word on whether or not Simulator will be updated so that AVFoundation also fails to work.
So, for now, Apple Watch is limited to controlling recording "on the phone" via watch extension to phone messaging which is supported in Apple Watch extensions.
Try using WKAudioFilePlayerItem ?
To use this class to play audio, you need to declare 3 variables:
var audioFile: WKAudioFileAsset!
var audioItem: WKAudioFilePlayerItem!
var audioPlayer: WKAudioFilePlayer!
They have different role inside the program. For audioFile is used to define NSURL. For example, if you have file called "bicycle.mp3", you can define the URL path like this :
let soundPath = NSBundle.mainBundle().pathForResource("bicycle", ofType: "mp3")
print("load file")
when you have a soundpath, you make it a NSURL inside audioFile:
audioFile = WKAudioFileAsset.init(URL: soundPathURL)
When you have a audioFile, you put it inside the audioPlayerItem
audioItem = WKAudioFilePlayerItem.init(asset: audioFile)
When you have audioItem, you put it inside the audioPlayer
`audioPlayer = WKAudioFilePlayer(playerItem: audioItem)`
Finally, you can put the code audioPlayer.play() where you want to play the sound
Enjoy!
Short answer? No. WatchKit doesn't currently offer access to any of the hardware in the Watch.
finally ended up with this:
#IBAction func playButtonTapped() {
let options = [WKMediaPlayerControllerOptionsAutoplayKey : "true"]
let filePath = NSBundle.mainBundle().pathForResource("1button", ofType: "wav")!
let fileUrl = NSURL.fileURLWithPath(filePath)
presentMediaPlayerControllerWithURL(fileUrl, options: options,
completion: { didPlayToEnd, endTime, error in
if let err = error {
print(err.description)
}
})
}