切换IOS下APP的后台运行模式

Mon 16 June 2014 | tags: iOS

iOS里APP有几种后台运行模式,例如在后台立即退出(如Cydia),在后台暂停(大部分app),在后台运行(播放音乐,广播,GPS定位等) 我搞了个切换的方法,用ssh链接到iOS设备上,传递你要更改的app的Info.plist文件就好了 程序:

#!/usr/bin/env python2.7

import plistlib as plib
import subprocess as subp
from contextlib import closing
import os, tempfile, shutil, re
from NameAppend import nameAppend

def parsePlistToString(plistFile=None):
 with closing(open(plistFile, 'rb')) as pfFH:
  plistString = pfFH.read()
  if plistString.find('bplist') == 0:
   isBinary = True
  else:
   isBinary = False
 if isBinary is True:
  out = subp.check_output('plutil.pl "{0}"'.format(plistFile), shell=True)
  try:
   plistTextFile = out.split('\n')[5].split(': ')[1]
   if not os.path.exists(plistTextFile):
    raise NameError, '{0}: no such file'.format(plistTextFile)
   with closing(open(plistTextFile, 'rb')) as pfFH:
    plistString = pfFH.read()
  finally:
   os.unlink(plistTextFile)
 plistData = plib.readPlistFromString(plistString)
 return plistData, isBinary

def switchMode(plistObj, mode=1, cap=4):
 if mode==1:
  plistObj.pop('UIBackgroundModes', None)
  plistObj['UIApplicationExitsOnSuspend']=True
 elif mode==2:
  plistObj.pop('UIBackgroundModes', None)
  plistObj.pop('UIApplicationExitsOnSuspend', None)
 elif mode==3:
  plistObj.pop('UIApplicationExitsOnSuspend', None)
  plistObj['UIBackgroundModes']=['audio', 'continuous', 'location', 'voip'][:cap]

def main(plistFile=None, backup=True, mode=1, cap=4):
 plistData, isBinary = parsePlistToString(plistFile)
 switchMode(plistData, mode, cap)

 tempOutFile = tempfile.NamedTemporaryFile(suffix='.plist')
 try:
  plib.writePlist(plistData, tempOutFile)
  tempOutFile.seek(0)
  if backup is True:
   os.system('mv -f "{0}" "{1}"'.format(plistFile, plistFile+'.bak'))
  if isBinary is True:
   subp.call('plutil.pl "{0}"'.format(tempOutFile.name), shell=True, stdout=open(os.devnull, 'w'))
   os.system('mv -f "{0}" "{1}"'.format(nameAppend(tempOutFile.name, '.binary'), plistFile))
  else:
   os.system('cp "{0}" "{1}"'.format(tempOutFile.name, plistFile))
 finally:
  tempOutFile.close()

if __name__ == '__main__':
 from argparse import ArgumentParser
 import sys
 parser = ArgumentParser()
 parser.add_argument('PLISTFILE', nargs='+', help='plist file', type=str)
 parser.add_argument('-b', '--backup', action='store_true', default=False, help='backup original plist file', dest='backup')
 parser.add_argument('-m', '--mode', choices=[1, 2, 3], type=int, default=2, dest='mode', help='choose one of three background modes')
 parser.add_argument('-c', '--capacity', choices=[1, 2, 3, 4], type=int, default=4, dest='cap', help='set how many features a app it will have if running background')
 args = parser.parse_args()
 for plistfile in args.PLISTFILE:
  main(plistFile=plistfile, backup=args.backup, mode=args.mode, cap=args.cap)