AVAudioFoundation issues when volume property is set - ios

I am writing a class which will be initialized for background audio.
`class BackgroundAudio: NSObject,AVAudioPlayerDelegate {
var audioPlayer:AVAudioPlayer
override init() {
audioPlayer = AVAudioPlayer()
super.init()
}
There is a function that mute the background audio in the class:
func mute() {
audioPlayer.setVolume(0, fadeDuration: 2)
}
Because a few View Controller in this project may need to control the volume, so I put the initialization in the AppDelegate file like this:
var backgroundAudioPlayer = BackgroundAudio()
There is an issue when I mute() is called
I have been debugging this a bit time, getting stuck at the moment. How to resolve this issue? Thanks in advance.

I’m positive that u can do this in the info setting rather than writing code....

Related

How to get data from one class to viewController?

Unfortunately I m newbie and cant solve this problem for days. the problem is I cant success to gather score from game engine class to view controller so that I can show it with a label.
here is I want to extract data from this func to global variables.
private func nextMove() {
current = .random(config)
if (well.hasCollision(current)) {
stopTimer()
scene.showGameOver(scores)
//extract score to another variable can be reached by another class
} else {
scene.show(current)
}
}
I tried many methods, creating a global class with init method, creating struct, creating protocol..etc that already written here, but never successed. any idea will be appriciated. thanks..
A Singleton could be what you're looking for.
Here's an example:
class ScoresSingleton {
static let sharedSession = ScoresSingleton()
var scores : Int = 0
}
You may then use globally by:
// Setting
ScoresSingleton.sharedSession.scores = 10
// Getting
var scores = ScoresSingleton.sharedSession.scores
Hope that helps.

How to make an object initialized in a iOS Storyboard a Singleton

Can you please advise me how to initialize a Singleton in an iOS storyboard? My understanding so far is that the standard pattern looks like this inside the class that we want to be a singleton and this code works:
class var sharedInstance: LibraryAPI {
struct Singleton {
static let instance = LibraryAPI()
}
return Singleton.instance
}
The same pattern does not work for MusicPlayer:
I'm making a custom MusicPlayer object that relies on AVPlayer to play audio. I would like this MusicPlayer to exist as soon as the App is activated. At present the MusicPlayer is create in the Storyboard to allow me to use IBOutlets and IBActions to connect the buttons and labels to the MusicPlayer. The challenge is the MusicPlayer gets deallocated when I navigate back up the viewController stack. As shown in the figure below.
Which methods can I override to see when the Storyboard creates and destroys the MusicPlayer? So far you can see that override init() is called but deinit is not. I'm not having any luck finding the answer in the docs or online yet.
It's possible there is a better way to design this app. I think that Singleton makes sense because there should only ever be one MusicPlayer. Only it's state will change throughout the life of the app.
Thank you for your advice.
class var sharedInstance: LibraryAPI {
struct Singleton {
static let instance = LibraryAPI()
}
return Singleton.instance
}
This seems very over-complicated. You can generally just use:
final class MusicPlayer {
let sharedInstance = MusicPlayer()
init() {}
}
Things do get a bit more complex if Something is not final, but usually it can be for singletons.
At present the MusicPlayer is create in the Storyboard to allow me to use IBOutlets and IBActions to connect the buttons and labels to the MusicPlayer.
This won't work. See rdar:25450179 for my version of the problem. The latest explanation from Apple is that this probably won't be fixed. It would require too much redesign of Storyboards. They may change their mind, but it's a big change.
The closest you can come is to expose the singleton through your class.
class MyClass: UIViewController {
var musicPlayer: MusicPlayer { return MusicPlayer.sharedInstance() }
}
But this probably isn't going to do what you want, either. Generally, you need to tie your IBOutlets directly to the view controller. The view controller can then proxy to other objects as needed.

Cocos2d iPHone SDK ccPhysicsCollisionPreSolve crashing while accessing object properties

I am working on Cocos2d iphone SDK and stuck with an issues. Check my code here.
Obstacle Class
#objc class Obstacle: CCNode {
weak var __pipe: CCSprite!
var ignoreCollision:Bool = false
override init!() {
super.init()
//NSLog("init plain")
userInteractionEnabled = true
ignoreCollision = false
}
func didLoadFromCCB() {
...
}
}
The main scene where I have placed collision delegate methods. The method is called once the player object collides with obstacle object.
func ccPhysicsCollisionPreSolve(pair: CCPhysicsCollisionPair!, hero: Player!, platform: Obstacle!) -> ObjCBool {
if !isGameOn {
NSLog("PLATFORM: Game finished")
return false
}
if platform.ignoreCollision {
platform.ignoreCollision = !platform.ignoreCollision
// For score updates
hudLayer.updatePlatform(++scorePlatforms)
}
return true
}
Now here, I am just trying to use simple Bool property from platform object and what I get is a crash. My app crashes on the if... condition statement where I am using that property. I am unable to get what is with this as I am simply using a property from object.
I checked the object and found platform shows me of type Some instead ob Obstacle. I have tried using
var p: Obstacle = platform as Obstacle
and replaced all platform with p but yet I am facing the crash. I thought the type now shows me some random hex number which might be the issue.
Can anyone help me here as I am unable to find out how I should access property from this platform object in ccPhysicsCollisionPreSolve method?
Sorry guys for the trouble but it was my mistake. I was understanding the same incorrectly.
The Obstacle class represents the platform as well as its background layer having tripple height of the device screen. But my ball collides only with that __pipe sprite in Obstacle class and I am referring the whole Obstacle class which is wrong.
I used platform.parent!.ignoreCollision and problem is solved. :)
This little miss costed me 3-4 days of R&D and work extra.

Presenting ViewController anew does not re-initialize it

I have a viewController (videocallVC) that I want to initialize every time it comes into view/loads.
Currently, the videocallVC only initialize the first time. If I leave the videocallVC, go to another viewController and come back to the videocallVC it holds the last session in memory and does not "refresh".
How can I make sure that every time I present the videocallVC it is initialized anew ?
import OpenTok
class videocallVC: UIViewController, OTSessionDelegate, OTSubscriberKitDelegate, OTPublisherDelegate {
#IBOutlet var subscribeView: UIView!
#IBOutlet var publishView: UIView!
let apiKey = "xxxxxxx"
var session : OTSession?
var publisher : OTPublisher?
var subscriber : OTSubscriber?
var connection : OTConnection?
override func viewDidLoad() {
super.viewDidLoad()
session = OTSession(
apiKey: apiKey,
sessionId: variableInstance.sessionID,
delegate: self)
}
override func viewWillAppear(animated: Bool) {
doConnect()
}
// MARK: - OpenTok Methods
/**
* Asynchronously begins the session connect process. Some time later, we will
* expect a delegate method to call us back with the results of this action.
*/
func doConnect() {
if let session = self.session {
var maybeError : OTError?
session.connectWithToken(variableInstance.tokboxToken, error: &maybeError)
if let error = maybeError {
showAlert(error.localizedDescription)
}
}
}
/**
* Sets up an instance of OTPublisher to use with this session. OTPubilsher
* binds to the device camera and microphone, and will provide A/V streams
* to the OpenTok session.
*/
func doPublish() {
publisher = OTPublisher(delegate: self)
var maybeError : OTError?
session?.publish(publisher, error: &maybeError)
if let error = maybeError {
showAlert(error.localizedDescription)
}
view.addSubview(publisher!.view)
publisher!.view.frame = publishView.frame
}
There is more code to the videocallVC but I gues this is sufficient to understand the problem.
Any help would be very much appreciated ! Thank you.
The method viewDidLoad is only called once. The method viewWillAppear is called every time the view will appear. So if you need to do things every time the view will appear, move it to that method (you may also use viewDidAppear if the UI behaviour makes sense). This may apply to the session = OTSession( ... ) snippet.
It may also be possible, that in your code things get initialized, then stored in a variable and later, if the variable is not nil no new initialization is done. You may solve that by setting those variables to nil in viewWillAppear.
However, without knowing all details, this may be a likely solution but still a shot in the dark :-)
how are your delegates store in OTSession and OTPublisher?
Are they weak?
If they are not weak, the View Controller can not be deinitialized, because there are still references to it. Maybe this can cause your problems.

Swift: permanent variable change through global files

I am working in between three files: Menu.swift, Main.swift and Game.swift.
In my Main.swift, I define the variable swipeNumber:
class Main {
var swipeNumber: Int = 0 {
didSet{
println("The new swipe number is \(swipeNumber)")
}
}
}
N.B. It is in a class so that I can reference the variable from other files, and the didSet property observer will function.
As you can see, its initial value (I think) is 0.
Then, in my Menu.swift, I retrieve the information from the Main class in Main.swift.
let main = Main()
I then have three buttons, which will, on touch, change the swipeNumber variable, based on which button was pressed.
class Menu: UIViewController {
#IBAction func pressedThreeSwipes(sender: AnyObject) {
main.swipeNumber = 3
}
#IBAction func pressedFiveSwipes(sender: AnyObject) {
main.swipeNumber = 5
}
#IBAction func pressedTenSwipes(sender: AnyObject) {
main.swipeNumber = 10
}
//...
}
When I run the program, my property observer appears to work, printing messages such as:
The new swipe number is 3
The new swipe number is 5
The new swipe number is 10
And in the Game class, (for troubleshooting purposes), I have another property observer, checking the integer of the variable swipeNumber when the button test is pressed:
class Game: UIView {
let main = Main()
func didMoveToView(view: UIView) {
/* Setup your scene here */
println("now")
println("\(main.swipeNumber)"
//Nothing happens here, suggesting that didMoveToView is failing
}
#IBAction func test(sender: AnyObject) {
println("\(main.swipeNumber)")
}
}
My func test prints a number, but sadly that number is not 3, 5, or 10. It's 0.
I think that the problem lies with my variable in Main.swift, however I am not sure.
Any advice or 'fixes', whether quick or lengthy, would be very greatly appreciated.
Thank you,
Will
You have different instances of your class Main, and they each carry a different value for the same properties.
You should try the Singleton pattern (see e.g. here or here).
When you call Main(), you are creating a new object...emphasis on NEW. It has no knowledge of what you've done to other objects of the same type. If you want to use the same object in different places, you need to make it a parameter and pass it into methods rather than creating a different object.

Resources