I'm trying to follow this tutorial to enable unlimited backgrounding on an app, using the new
objc_util(in the beta).
Do you think it will work? Is the tutorial still relevant with the latest iOS versions?
The code looks pretty simple:
@property (nonatomic, strong) AVPlayer *player;
NSError *sessionError = nil; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&sessionError]; AVPlayerItem *item = [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"silence" withExtension:@"mp3"]]; [self setPlayer:[[AVPlayer alloc] initWithPlayerItem:item]]; // this makes sure our player keeps working after the silence ends [[self player] setActionAtItemEnd:AVPlayerActionAtItemEndNone]; [[self player] play];
I'm not able to fully implement it due to my lack of knowledges. In particular I'm not able to access a class' constant using
Once you load the framework you can access the classes you need with
You can even call private APIs, but this is useless since iOS 7 because apps must have certain entitlements to be able to trigger certain methods. Here is an example to open Siri (that fails silently).
from objc_util import * # Load the framework ObjCClass('NSBundle').bundleWithPath_('/System/Library/PrivateFrameworks/AccessibilityUtilities.framework').load() # "Import" one of its class AXSpringBoardServer = ObjCClass('AXSpringBoardServer') # Call a class' method AXSpringBoardServer.alloc().openSiri()
About the dynamic library, I can't help you.
That's the point, if an app is playing audio it doesn't get “killed”. If you try to run an endless script and meanwhile run some heavy games iOS will “kill” Pythonista and so your script to free up the RAM.
The cool part is that the solution provided by omz does not interfere at all with playing audio in the system.
Meanwhile I got my hands back to my Mac and wrote the script I couldn't figure out:
from objc_util import * from time import sleep from datetime import datetime # "Imports" AVAudioSession = ObjCClass('AVAudioSession') AVPlayer = ObjCClass('AVPlayer') AVPlayerItem = ObjCClass('AVPlayerItem') NSURL = ObjCClass('NSURL') # Set Pythonista app to play non-blocking, 'mixed with others' sounds audio_session = AVAudioSession.sharedInstance() audio_session.setCategory_withOptions_error_('AVAudioSessionCategoryPlayback', 1, None) # Create the item to play sound = NSURL.fileURLWithPath_('silence.mp3') item = AVPlayerItem.playerItemWithURL_(sound) # Play the sound (only once) player = AVPlayer.alloc().initWithPlayerItem_(item) player.setActionAtItemEnd_(2) player.play() while True: print 'Still running', datetime.now() sleep(1)
It does seem to work, as the omz’ solution, but I don't know if there is efficiency differences.
Thank you, omz! The code works for me. What does
sound.Player.number_of_loops = -1mean? Is the sound played continuously? Does it consume CPU in background?
Also, I tried this:
from sound import Player player = Player('') player.number_of_loops = -1 player.play()
and it still works, even with files that doesn't exist.
Sorry, Obelisk, but I don't understand your comment. The idea is to play a silent sound to keep scripts running in the background, forever.