AVAudioPath not working - Swift - xcode

I am trying to play a song based on the instrument the user selects. Here is my code:
#IBAction func play(sender: AnyObject) {
if isPlaying == false {
player.play()
isPlaying = true
}
}
#IBAction func stop(sender: AnyObject) {
if isPlaying == true {
player.stop()
isPlaying = false
}
}
#IBAction func pause(sender: AnyObject) {
if isPlaying == true {
isPlaying = false
player.pause()
}
}
var player = AVAudioPlayer()
var audioPath = NSBundle.mainBundle().pathForResource("Iditarod Bass", ofType: "m4a")
var isPlaying = Bool()
#IBOutlet var instrumentSelect: UISegmentedControl!
#IBAction func didChangeInstrument(sender: AnyObject) {
if isPlaying == false {
if instrumentSelect.selectedSegmentIndex == 0 {
audioPath = NSBundle.mainBundle().pathForResource("Iditarod Bass", ofType: "m4a")
do {
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
} catch {
}
} else if instrumentSelect.selectedSegmentIndex == 1 {
audioPath = NSBundle.mainBundle().pathForResource("Iditarod Cello", ofType: "m4a")
do {
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
} catch {
}
} else if instrumentSelect.selectedSegmentIndex == 2 {
audioPath = NSBundle.mainBundle().pathForResource("Iditarod Viola", ofType: "m4a")
do {
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
} catch {
}
} else if instrumentSelect.selectedSegmentIndex == 3 {
audioPath = NSBundle.mainBundle().pathForResource("Iditarod Violin 1", ofType: "m4a")
do {
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
} catch {
}
} else if instrumentSelect.selectedSegmentIndex == 4 {
audioPath = NSBundle.mainBundle().pathForResource("Iditarod Violin 2", ofType: "m4a")
do {
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
} catch {
}
}
}
}
All of them work fine except for the instrumentSelect.selectedSegmentIndex == 1. I don't know why. I get an EXC_BAD_INSTRUCTION that says fatal error: unexpectedly found nil while unwrapping an Optional value. The file is working fine, and I have cleaned the project numerous times. I have typed everything correctly. Why is that one not working? I am very confused about this, and I appreciate your help.

The file was not being added to the app target. It was added to the project only. Thanks #matt for helping me.

Related

Capture video : SwiftUI

I want to capture a video through back camera using swiftUI. I can not find the proper solution on on video recording. I implement the code that record video automatically when view is open But I want to start the recording on bottom button click. Can someone please guide me on this.
import SwiftUI
import AVKit
struct RecordingView: View {
#State private var timer = 5
#State private var onComplete = false
#State private var recording = false
var body: some View {
ZStack {
VideoRecordingView(timeLeft: $timer, onComplete: $onComplete, recording: $recording)
VStack {
Button(action: {self.recording.toggle()}, label: {
ZStack {
Circle()
.fill(Color.white)
.frame(width: 65, height: 65)
Circle()
.stroke(Color.white,lineWidth: 2)
.frame(width: 75, height: 75)
}
})
Button(action: {
self.timer -= 1
print(self.timer)
}, label: {
Text("Toggle timer")
})
.foregroundColor(.white)
.padding()
Button(action: {
self.onComplete.toggle()
}, label: {
Text("Toggle completion")
})
.foregroundColor(.white)
.padding()
}
}
}
}
This is For recordingView
struct VideoRecordingView: UIViewRepresentable {
#Binding var timeLeft: Int
#Binding var onComplete: Bool
#Binding var recording: Bool
func makeUIView(context: UIViewRepresentableContext<VideoRecordingView>) -> PreviewView {
let recordingView = PreviewView()
recordingView.onComplete = {
self.onComplete = true
}
recordingView.onRecord = { timeLeft, totalShakes in
self.timeLeft = timeLeft
self.recording = true
}
recordingView.onReset = {
self.recording = false
self.timeLeft = 30
}
return recordingView
}
func updateUIView(_ uiViewController: PreviewView, context: UIViewRepresentableContext<VideoRecordingView>) {
}
}
extension PreviewView: AVCaptureFileOutputRecordingDelegate{
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
print(outputFileURL.absoluteString)
}
}
class PreviewView: UIView {
private var captureSession: AVCaptureSession?
private var shakeCountDown: Timer?
let videoFileOutput = AVCaptureMovieFileOutput()
var recordingDelegate:AVCaptureFileOutputRecordingDelegate!
var recorded = 0
var secondsToReachGoal = 30
var onRecord: ((Int, Int)->())?
var onReset: (() -> ())?
var onComplete: (() -> ())?
init() {
super.init(frame: .zero)
var allowedAccess = false
let blocker = DispatchGroup()
blocker.enter()
AVCaptureDevice.requestAccess(for: .video) { flag in
allowedAccess = flag
blocker.leave()
}
blocker.wait()
if !allowedAccess {
print("!!! NO ACCESS TO CAMERA")
return
}
// setup session
let session = AVCaptureSession()
session.beginConfiguration()
let videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera,
for: .video, position: .front)
guard videoDevice != nil, let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice!), session.canAddInput(videoDeviceInput) else {
print("!!! NO CAMERA DETECTED")
return
}
session.addInput(videoDeviceInput)
session.commitConfiguration()
self.captureSession = session
}
override class var layerClass: AnyClass {
AVCaptureVideoPreviewLayer.self
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var videoPreviewLayer: AVCaptureVideoPreviewLayer {
return layer as! AVCaptureVideoPreviewLayer
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
recordingDelegate = self
startTimers()
if nil != self.superview {
self.videoPreviewLayer.session = self.captureSession
self.videoPreviewLayer.videoGravity = .resizeAspect
self.captureSession?.startRunning()
self.startRecording()
} else {
self.captureSession?.stopRunning()
}
}
private func onTimerFires(){
print("🟢 RECORDING \(videoFileOutput.isRecording)")
secondsToReachGoal -= 1
recorded += 1
onRecord?(secondsToReachGoal, recorded)
if(secondsToReachGoal == 0){
stopRecording()
shakeCountDown?.invalidate()
shakeCountDown = nil
onComplete?()
videoFileOutput.stopRecording()
}
}
func startTimers(){
if shakeCountDown == nil {
shakeCountDown = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] (timer) in
self?.onTimerFires()
}
}
}
func startRecording(){
captureSession?.addOutput(videoFileOutput)
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let filePath = documentsURL.appendingPathComponent("tempPZDC")
videoFileOutput.startRecording(to: filePath, recordingDelegate: recordingDelegate)
}
func stopRecording(){
videoFileOutput.stopRecording()
print("🔴 RECORDING \(videoFileOutput.isRecording)")
}
}
Modify your code by this
struct VideoRecordingView: UIViewRepresentable {
#Binding var timeLeft: Int
#Binding var onComplete: Bool
#Binding var recording: Bool
func makeUIView(context: UIViewRepresentableContext<VideoRecordingView>) -> PreviewView {
let recordingView = PreviewView()
recordingView.onComplete = {
self.onComplete = true
}
recordingView.onRecord = { timeLeft, totalShakes in
self.timeLeft = timeLeft
self.recording = true
}
recordingView.onReset = {
self.recording = false
self.timeLeft = 30
}
return recordingView
}
func updateUIView(_ uiViewController: PreviewView, context: UIViewRepresentableContext<VideoRecordingView>) {
if recording {
uiViewController.start()
}
}
}
extension PreviewView: AVCaptureFileOutputRecordingDelegate{
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
print(outputFileURL.absoluteString)
}
}
class PreviewView: UIView {
private var captureSession: AVCaptureSession?
private var shakeCountDown: Timer?
let videoFileOutput = AVCaptureMovieFileOutput()
var recordingDelegate:AVCaptureFileOutputRecordingDelegate!
var recorded = 0
var secondsToReachGoal = 30
var onRecord: ((Int, Int)->())?
var onReset: (() -> ())?
var onComplete: (() -> ())?
init() {
super.init(frame: .zero)
var allowedAccess = false
let blocker = DispatchGroup()
blocker.enter()
AVCaptureDevice.requestAccess(for: .video) { flag in
allowedAccess = flag
blocker.leave()
}
blocker.wait()
if !allowedAccess {
print("!!! NO ACCESS TO CAMERA")
return
}
// setup session
let session = AVCaptureSession()
session.beginConfiguration()
let videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera,
for: .video, position: .front)
guard videoDevice != nil, let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice!), session.canAddInput(videoDeviceInput) else {
print("!!! NO CAMERA DETECTED")
return
}
session.addInput(videoDeviceInput)
session.commitConfiguration()
self.captureSession = session
}
override class var layerClass: AnyClass {
AVCaptureVideoPreviewLayer.self
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var videoPreviewLayer: AVCaptureVideoPreviewLayer {
return layer as! AVCaptureVideoPreviewLayer
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
recordingDelegate = self
}
func start() {
startTimers()
if nil != self.superview {
self.videoPreviewLayer.session = self.captureSession
self.videoPreviewLayer.videoGravity = .resizeAspect
self.captureSession?.startRunning()
self.startRecording()
} else {
self.captureSession?.stopRunning()
}
}
private func onTimerFires(){
print("🟢 RECORDING \(videoFileOutput.isRecording)")
secondsToReachGoal -= 1
recorded += 1
onRecord?(secondsToReachGoal, recorded)
if(secondsToReachGoal == 0){
stopRecording()
shakeCountDown?.invalidate()
shakeCountDown = nil
onComplete?()
videoFileOutput.stopRecording()
}
}
func startTimers(){
if shakeCountDown == nil {
shakeCountDown = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] (timer) in
self?.onTimerFires()
}
}
}
func startRecording(){
captureSession?.addOutput(videoFileOutput)
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let filePath = documentsURL.appendingPathComponent("tempPZDC")
videoFileOutput.startRecording(to: filePath, recordingDelegate: recordingDelegate)
}
func stopRecording(){
videoFileOutput.stopRecording()
print("🔴 RECORDING \(videoFileOutput.isRecording)")
}
}

Unable to access user selected file via NSOpenPanel in FFMPEG process in macOS app

I am new to macOS development via SwiftUI. I'm trying to run a FFMPEG process after I selected a MP4 file via NSOpenPanel. However, the FFMPEG responded with:
file:///Users/MyUsername/Documents/Video.mp4: No such file or directory
Here is my simple codes:
import SwiftUI
struct ContentView: View {
#State var selectedURL: URL?
var body: some View {
VStack {
if selectedURL != nil {
Text("Selected: \(selectedURL!.absoluteString)")
} else {
Text("Nothing selected")
}
Button(action: {
let panel = NSOpenPanel()
panel.allowedFileTypes = ["mp4"]
panel.canChooseDirectories = false
panel.canCreateDirectories = false
panel.allowsMultipleSelection = false
let result = panel.runModal()
if result == .OK {
self.selectedURL = panel.url
let savePath = self.getDownloadDirectory().appendingPathComponent("video.webm")
self.convertVideo(inputFilePath: self.selectedURL!.absoluteString, outputFilePath: savePath.absoluteString, callback: {(s) in
// omit the callback at this moment
})
}
}) {
Text("Select File")
}
}
.frame(width: 640, height: 480)
}
func getDownloadDirectory() -> URL {
let paths = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask)
return paths[0]
}
func convertVideo(inputFilePath: String, outputFilePath: String,
callback: #escaping (Bool) -> Void) -> (Process, DispatchWorkItem)? {
guard let launchPath = Bundle.main.path(forResource: "ffmpeg", ofType: "") else {
return nil
}
let process = Process()
let task = DispatchWorkItem {
process.launchPath = launchPath
process.arguments = [
"-y",
"-i", inputFilePath,
"-vcodec", "vp8",
"-acodec", "libvorbis",
"-pix_fmt", "yuva420p",
"-metadata:s:v:0",
"alpha_mode=\"1\"",
"-auto-alt-ref", "0",
outputFilePath
]
process.standardInput = FileHandle.nullDevice
process.launch()
process.terminationHandler = { process in
callback(process.terminationStatus == 0)
}
}
DispatchQueue.global(qos: .userInitiated).async(execute: task)
return (process, task)
}
}
What did I miss to allow FFMPEG process to access my selected file? Thanks!
Try to use .path instead of .absoluteString
self.convertVideo(inputFilePath: self.selectedURL!.path,
outputFilePath: savePath.absoluteString, callback: {(s) in

PayU Money Gateway iOS Swift

I want to integrate the payU Money sdk in my app using swift2.0
I am using this sdk: https://github.com/payu-intrepos/Documentations/wiki/8.1-NEW-iOS-Seamless-SDK-integration
Where to create the test account for testing.
import UIKit
var merchantKey="your live merchant key"
var salt="your live merchant salt"
var PayUBaseUrl="https://secure.payu.in"
class PaymentScreen: UIViewController,UIWebViewDelegate {
#IBOutlet weak var myWebView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
self.initPayment()
}
func initPayment() {
var i = arc4random()
let amount = "1"
let productInfo = "Order"
let firstName = "Sample name"
let email = "abc#gmail.com"
let phone = "9999119911"
let sUrl = "https://www.google.com"
let fUrl = "https://www.bing.com"
let service_provider = "payu_paisa"
let strHash:String = self.sha1(String.localizedStringWithFormat("%d%#", i, NSDate()))
let rangeOfHello = Range(start: strHash.startIndex,
end: strHash.startIndex.advancedBy(20))
let txnid1 = strHash.substringWithRange(rangeOfHello)
let hashValue = String.localizedStringWithFormat("%#|%#|%#|%#|%#|%#|||||||||||%#",merchantKey,txnid1,amount,productInfo,firstName,email,salt)
let hash=self.sha1(hashValue)
let postStr = "txnid="+txnid1+"&key="+merchantKey+"&amount="+amount+"&productinfo="+productInfo+"&firstname="+firstName+"&email="+email+"&phone="+phone+"&surl="+sUrl+"&furl="+fUrl+"&hash="+hash+"&service_provider="+service_provider
let url = NSURL(string: String.localizedStringWithFormat("%#/_payment", PayUBaseUrl))
print("check my url", url, postStr)
let request = NSMutableURLRequest(URL: url!)
do {
let postLength = String.localizedStringWithFormat("%lu",postStr.characters.count)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Current-Type")
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.HTTPBody = postStr.dataUsingEncoding(NSUTF8StringEncoding)
myWebView.loadRequest(request)
} catch {
}
}
func webViewDidStartLoad(webView: UIWebView) {
}
func webViewDidFinishLoad(webView: UIWebView) {
let requestURL = self.myWebView.request?.URL
let requestString:String = (requestURL?.absoluteString)!
if requestString.containsString("https://www.google.com") {
print("success payment done")
}
else if requestString.containsString("https://www.bing.com") {
print("payment failure")
}
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
print("double failure")
}
func sha1(toEncrypt:String) -> String {
let data = toEncrypt.dataUsingEncoding(NSUTF8StringEncoding)!
var digest = [UInt8](count:Int(CC_SHA512_DIGEST_LENGTH), repeatedValue: 0)
CC_SHA512(data.bytes, CC_LONG(data.length), &digest)
let hexBytes = digest.map { String(format: "%02x", $0) }
return hexBytes.joinWithSeparator("")
}
}
// Swift 4
import UIKit
import SystemConfiguration
import Foundation
class PayUMoneyViewController: UIViewController, UIWebViewDelegate, UIAlertViewDelegate {
#IBOutlet weak var webView: UIWebView!
var merchantKey = "YOUR_MARCHANT_KEY"
var salt = "YOUR_SALT_KEY"
var PayUBaseUrl = "https://secure.payu.in"
var SUCCESS_URL = "https://www.payumoney.com/payments/guestcheckout/#/success"
var FAILED_URL = "https://www.PayUmoney.com/mobileapp/PayUmoney/failure.php"
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
var request = NSMutableURLRequest()
override func viewDidLoad() {
super.viewDidLoad()
self.webView.delegate = self
self.payPayment()
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.plain, target: self, action: #selector(PayUMoneyViewController.back(sender:)))
self.navigationItem.leftBarButtonItem = newBackButton
}
#objc func back(sender: UIBarButtonItem) {
let alert = UIAlertController(title: "Cancel !", message: "Do you really want to cancel the transaction ?", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.default, handler: cancelTransaction))
alert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
func cancelTransaction( action : UIAlertAction)
{
_ = navigationController?.popToRootViewController(animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func payPayment() {
var i = arc4random()
let amount = "1"
let productInfo = "Transport"
let firstName = USER_FIRST_NAME // Geet
let email = USER_EMAIL // geetbasakare#gmail.com
let phone = USER_MOBILE_NO // 1234567890
let sUrl = "https://www.google.com"
let fUrl = "https://www.bing.com"
let service_provider = "payu_paisa"
let strHash:String = self.sha1(toEncrypt: String.localizedStringWithFormat("%d%#", i, NSDate()));
let r1 = strHash.range(of: strHash)!
// String range to NSRange:
let n1 = NSRange(r1, in: strHash)
print((strHash as NSString).substring(with: n1)) //
// NSRange back to String range:
let r2 = Range(n1, in: strHash)!
print(strHash.substring(with: r2))
let rangeOfHello = Range(n1, in: strHash)!
let txnid1 = strHash.substring(with: rangeOfHello)
let hashValue = String.localizedStringWithFormat("%#|%#|%#|%#|%#|%#|||||||||||%#",merchantKey,txnid1,amount,productInfo,firstName,email,salt)
let hash = self.sha1(toEncrypt: hashValue)
let postStr = "txnid="+txnid1+"&key="+merchantKey+"&amount="+amount+"&productinfo="+productInfo+"&firstname="+firstName+"&email="+email+"&phone="+phone+"&surl="+sUrl+"&furl="+fUrl+"&hash="+hash+"&service_provider="+service_provider
let url = NSURL(string: String.localizedStringWithFormat("%#/_payment", PayUBaseUrl))
print("check my url", url as Any, postStr)
let request = NSMutableURLRequest(url: url! as URL)
do {
let postLength = String.localizedStringWithFormat("%lu",postStr.characters.count)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Current-Type")
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.httpBody = postStr.data(using: String.Encoding.utf8)
webView.loadRequest(request as URLRequest)
} catch {
print(error)
}
}
func webViewDidFinishLoad(_ webView: UIWebView) {
let requestURL = self.webView.request?.url
let requestString:String = (requestURL?.absoluteString)!
if (requestString == SUCCESS_URL) {
print("success payment done")
}
else if (requestString == FAILED_URL) {
print("payment failure")
}
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
print("double failure")
}
func sha1(toEncrypt: String) -> String {
var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH))
if let data = toEncrypt.data(using: String.Encoding.utf8) {
let value = data as NSData
CC_SHA512(value.bytes, CC_LONG(data.count), &digest)
}
var digestHex = ""
for index in 0..<Int(CC_SHA512_DIGEST_LENGTH) {
digestHex += String(format: "%02x", digest[index])
}
return digestHex
}
/*
func sha1(toEncrypt:String) -> String {
var data = toEncrypt.data(using: String.Encoding.utf8)!
var digest = [UInt8](repeating: 0, count:Int(CC_SHA512_DIGEST_LENGTH))
_ = data.withUnsafeBytes {messageBytes in
CC_SHA512(messageBytes, CC_LONG(data.count), &digest)
}
let hexBytes = digest.map { String(format: "%02x", $0) }
return hexBytes.joined(separator: "")
}
*/
}
You can create a test account as described in the following help documentation, and you need not perform KYC in this regard. Later, you can use the Key and Salt on the Payment Gateway page of the Dashboard.
https://devguide.payu.in/low-code-web-sdk/getting-started-low-code-web-sdk/register-for-a-test-merchant-account/

Error after upgrading Xcode Expected declaration

#IBAction func newPhoto(sender: AnyObject) {
if isCameraAvailable() && doesCameraSupportTakingPhotos(){
imagePicker.sourceType = .Camera
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = true
imagePicker.delegate = self
presentViewController(imagePicker, animated: true, completion: nil)
}
}
else {
print("Camera is not available")
}
The error occurs in place of else { -expected Declaration
- Help me please!
Move One } before else to the end of If else statement
#IBAction func newPhoto(sender: AnyObject) {
if isCameraAvailable() && doesCameraSupportTakingPhotos(){
imagePicker.sourceType = .Camera
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = true
imagePicker.delegate = self
presentViewController(imagePicker, animated: true, completion: nil)
}
else {
print("Camera is not available")
}
}

Trouble Debugging NSTimer

I am trying to have an image show up for 1 second and disappear after the 1 second is up. When I build my app it works fine but when I run my app it crashes. Here is my code:
var flashTimer = NSTimer()
var timerCounter = 0
var currentTime = 0
var randomImageGeneratorNumber = 0
var flashingImageView = UIImageView()
var flashButton = UIButton()
#IBAction func flashButton(sender: UIButton) {
var randomImageGeneratorNumber = arc4random_uniform(6) + 1
if flashButton.hidden {
flashButton.hidden = true
flashingImageView.hidden = false
}
if randomImageGeneratorNumber == 1 {
flashingImageView.image = UIImage(named: "Image1.png")
}
if randomImageGeneratorNumber == 2 {
flashingImageView.image = UIImage(named: "Image2.png")
}
if randomImageGeneratorNumber == 3 {
flashingImageView.image = UIImage(named: "Image3.png")
}
if randomImageGeneratorNumber == 4 {
flashingImageView.image = UIImage(named: "Image4.png")
}
if randomImageGeneratorNumber == 5 {
flashingImageView.image = UIImage(named: "Image5.png")
}
if randomImageGeneratorNumber == 6 {
flashingImageView.image = UIImage(named: "Image6.png")
}
var currentTime = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "timerFunc", userInfo: nil, repeats: false)
func timerFunc(sender: AnyObject){
flashingImageView.hidden = true;
}
}
The error in the debugger output is:
[Flash_Facts.ViewController timerFunc]: unrecognized selector sent to instance 0x7f9ceb774810
I am not sure how to fix this. Any suggestions?
Thanks in advance.
The problem is that you have to create your function outside the IBAction function. The same applies to your timer var ( currentTime )
var currentTime = NSTimer()
func timerFunc() {
flashButton.hidden = !flashButton.hidden
flashingImageView.hidden = !flashingImageView.hidden
}
#IBAction func flashButton(sender: UIButton) {
flashButton.hidden = !flashButton.hidden
flashingImageView.hidden = !flashingImageView.hidden
flashingImageView.image = UIImage(named: "Image\(arc4random_uniform(6) + 1).png")
currentTime = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "timerFunc", userInfo: nil, repeats: false)
}

Resources