My local notifications are working, and the alert is showing, however the sound is not playing. I am testing on a device as I know it won't play in the simulator.
let notificationAlert = UILocalNotification()
class DailyAlarmViewController: UIViewController {
#IBOutlet weak var timePicker: UIDatePicker!
#IBAction func alarmSetButton(sender: AnyObject) {
notificationAlert.fireDate = timePicker.date
notificationAlert.timeZone = NSTimeZone.defaultTimeZone()
notificationAlert.repeatInterval = NSCalendarUnit.Day
notificationAlert.alertAction = "Open Survive to Thrive Nation!"
notificationAlert.alertBody = "Time to wake up and complete your Journal!"
notificationAlert.soundName = "Alarm_Clock.wav"
UIApplication.sharedApplication().scheduleLocalNotification(notificationAlert)
}
#IBAction func cancelAlarm(sender: AnyObject) {
UIApplication.sharedApplication().cancelLocalNotification(notificationAlert)
}
Do I need to add Background Mode or Inter App Audio? Any thoughts would be appreciated.
You must check the .wav file had add to the reaource of the app.
Can you try instead of Alarm_Clock.wav to use the default alarm sound UILocalNotificationDefaultSoundName. If it works, then may be the problem is with the Alarm_Clock.wav.
Related
This question already has answers here:
How to handle background audio playing while iOS device is locked or on another application?
(6 answers)
Closed 2 years ago.
I've created an app for playing radio stream from URL, but it is not playing audio when app is on background. I checked audio and airplay in background modes in app settings but still it does not work. Do I need to add some permissions in appdelegate? Any ideas? Thank you in advance for your help. Here is my code:
import UIKit
import AVKit
class ViewController: UIViewController {
var player : AVPlayer!
var dict = NSDictionary()
#IBOutlet weak var ArtistLabel: UILabel!
#IBAction func playButtonPressed(_ sender: UIButton){
let url = "https://test.com/stream.mp3"
player = AVPlayer(url: URL(string: url)!)
player.volume = 1.0
player.rate = 1.0
player.play()
}
#IBAction func stopButtonStopped(sender: UIButton) {
player.pause()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
overrideUserInterfaceStyle = .light
}
}
You need to set your app Capabilities Background Modes (Audio and AirPlay) and set your AVAudioSession category to AVAudioSessionCategoryPlayback and set it active.
Please Refer to this link below :
How to play audio in background with Swift?
I'm currently making a metronome app, it uses AKMetronome for the core part since it has the callback function, I need the callback function to visualize the beat, I also want to use it for customized click sound (and I'll mute the original AKMetronome sound, but it'll still play, just without the original sound).
Now, I have two wav files which are customized click sound, there will be two AKPlayers to play it, and the AKPlayers need to be triggered on every AKMetronome beat's callback.
Since AKPlayer and AKMetronome are both need to be played, I put them in an AKMixer, like this:
let mixer = AKMixer(playerA, playerB, metronome)
AudioKit.output = mixer
and the callback will call this func:
func playAudio() {
playerA.play()
playerB.play()
}
Then, when playerA.play() is executed, it'll crash.
This is the error message:
AURemoteIO::IOThread (11): EXC_BAD_ACCESS (code=1, address=0xffff9ffffdb0e360)
same error message in screenshot
If I only put one of the AKPlayer object or AKMetronome in the AKMixer, then it works fine.
I can't understand the error message, also don't know why this happens.
Any help would be appreciated.
Here is the full code:
var playerA: AKPlayer!
var playerB: AKPlayer!
var clickA: AKAudioFile?
var clickB: AKAudioFile?
var metronome: AKMetronome?
override func viewDidLoad() {
super.viewDidLoad()
prepareAudio()
metronome!.start()
}
func prepareAudio() {
clickA = try? AKAudioFile(readFileName: "Click1A.wav")
clickB = try? AKAudioFile(readFileName: "Click1B.wav")
playerA = AKPlayer(audioFile: clickA!)
playerA.buffering = .always
playerB = AKPlayer(audioFile: clickB!)
playerB.buffering = .always
//metronome
metronome = AKMetronome.init()
metronome!.subdivision = 4
metronome!.frequency1 = 1000
metronome!.frequency2 = 800
metronome!.tempo = 60
metronome!.callback = {
self.playAudio()
}
let mixer = AKMixer(playerA, playerB, metronome)
AudioKit.output = mixer
do {
try AudioKit.start()
} catch {
print("audiokit start fail!")
}
}
func playAudio() {
playerA.play()
playerB.play()
}
I want create a app to save the notes, reminders, daily task and want to display these on the Lockscreen and when user tap the note, app will open and display the task on its screen with Customised view and background. I've done a lot of search about how to do this but got no luck.
For reference
ScreenMemo, Task Paper and many more apps doing the same.
I've no Idea which library to use to achieve this. Please help and share your code/links for better understandability.
Thanks
What you can do is to let your app display a Local Notification. Local notification pops up on the Lock screen with your desired text and clicking on it will open your App. You can as well configure which page to open the app if the notification is clicked.
Here is an example:
Step1:
import UIKit
Step2:
override func viewDidLoad() {
super.viewDidLoad()
let notification = UILocalNotification()
if #available(iOS 8.2, *) {
notification.alertTitle = "Notification Title!"
} else {
// Fallback on earlier versions
}
notification.alertBody = "This is the notification text"
notification.fireDate = NSDate(timeIntervalSinceNow: 10)
notification.applicationIconBadgeNumber = 1
notification.timeZone = NSTimeZone.defaultTimeZone()
notification.soundName = UILocalNotificationDefaultSoundName
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
//showinitial = false
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Happy coding!
i'm working on an ios app which will send notification after the app being sent to the background. I only want the notification to work when the user set a value to true in MainviewController.swift. So I have something like this :
func setDelegateToTrue () {
Appdelegate().setToStart()
}
func setDelegateToFalse () {
Appdelegate().setToEnd()
}
and in my Appdelegate.swift, I have something like this :
var started = false
func applicationDidEnterBackground(application: UIApplication) {
if(started) {
let notification: UILocalNotification = UILocalNotification()
notification.category = "FIRST_CATEGORY"
notification.alertBody = "do not forget your app"
notification.repeatInterval = NSCalendarUnit.Day
notification.timeZone = NSTimeZone.defaultTimeZone()
UIApplication.sharedApplication().scheduleLocalNotification(notification)
started = false
}
}
func setToStart() {
started = true
}
func setToEnd() {
started = false
}
The notification works fine while there is no if statement, however, when I have the if statement and call setDelegateToTrue() in viewdidload, it stopped working. It seems like the boolean value started was to changed after calling setToStart(), but I actually can print things out of setToStart(). Can anyone help me?
Your problem is that you're creating a new instance of AppDelegate when you run AppDelegate().setToStart(). So, when the application delegate it called later it's flag is still set to false, because you set a flag on a different instance (which was immediately destroyed).
To do what you're currently trying to you need to get the delegate from UIApplication (the sharedApplication) and set the flag on that.
Bear this in mind when communication with view controllers and such in OO languages as you always need to get the instance you want to talk to rather than create a new one.
For this behaviour you can make use of NSUserDefault:
Set the value inside the Main ViewController as:
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "shouldSendNotification")
And access this user default in applicationDidEnterBackground of app delegate as follow:
func applicationDidEnterBackground(application: UIApplication) {
let shouldSendNotification = NSUserDefaults.standardUserDefaults().boolForKey("shouldSendNotification")
if shouldSendNotification {
let notification: UILocalNotification = UILocalNotification()
notification.category = "FIRST_CATEGORY"
notification.alertBody = "do not forget your app"
notification.repeatInterval = NSCalendarUnit.Day
notification.timeZone = NSTimeZone.defaultTimeZone()
UIApplication.sharedApplication().scheduleLocalNotification(notification)
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "shouldSendNotification")
}
}
You need to do is
func setDelegateToTrue () {
AppDelegate.sharedAppDelegate().setToStart()
}
func setDelegateToFalse () {
AppDelegate.sharedAppDelegate().setToEnd()
}
Xcode Version - 6.1.1, IOS Version on Device(IPHONE 4S) - 8.1.2
class ViewController2: UIViewController,AVAudioPlayerDelegate {
var player: AVPlayer! = nil
override func viewDidLoad() {
super.viewDidLoad()
var steamingURL:NSURL! = NSURL(string:"http://yflvr.com:8080/data/songs1/mp3/16287239.mp3")
player = AVPlayer(URL: steamingURL)
player.play()
}
}
Check the spelling of your filename. The device is case-sensitive, the simulator is not... Are you sure it is not just delayed?
Also, check if your ringer is off, you won't hear any sound when it's off. To prevent that, use
var session: AVAudioSession = AVAudioSession.sharedInstance();
session.setCategory(AVAudioSessionCategoryPlayback, error: nil)
from here
You can also set an observer on the AVPlayer.status property to debug its changing status
Here they have used AVAudioPlayer and added a call to prepareToPlay()