Skip to content

Commit 1ec3595

Browse files
committed
show how to use MPRemoteCommandCenter
1 parent af4c7da commit 1ec3595

File tree

10 files changed

+788
-0
lines changed

10 files changed

+788
-0
lines changed
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
// !$*UTF8*$!
2+
{
3+
archiveVersion = 1;
4+
classes = {
5+
};
6+
objectVersion = 46;
7+
objects = {
8+
9+
/* Begin PBXBuildFile section */
10+
3241C22D1BB5C6F300D09188 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3241C22C1BB5C6F300D09188 /* LaunchScreen.storyboard */; };
11+
3280FA5E1997C57900EA8B8B /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3280FA5D1997C57900EA8B8B /* Player.swift */; };
12+
3280FA601997C97700EA8B8B /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3280FA5F1997C97700EA8B8B /* ViewController.swift */; };
13+
3280FA621997D07D00EA8B8B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3280FA611997D07D00EA8B8B /* AppDelegate.swift */; };
14+
C9592EC01823107000CE45EA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9592EBE1823107000CE45EA /* Main.storyboard */; };
15+
C9592EC51823107000CE45EA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C9592EC41823107000CE45EA /* Assets.xcassets */; };
16+
C9592EE51823110800CE45EA /* test.aif in Resources */ = {isa = PBXBuildFile; fileRef = C9592EE41823110800CE45EA /* test.aif */; };
17+
/* End PBXBuildFile section */
18+
19+
/* Begin PBXFileReference section */
20+
3241C22C1BB5C6F300D09188 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
21+
3280FA5D1997C57900EA8B8B /* Player.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Player.swift; sourceTree = "<group>"; };
22+
3280FA5F1997C97700EA8B8B /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
23+
3280FA611997D07D00EA8B8B /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
24+
C9592EA91823107000CE45EA /* ch27p912ducking.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ch27p912ducking.app; sourceTree = BUILT_PRODUCTS_DIR; };
25+
C9592EB41823107000CE45EA /* ch27p912ducking-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ch27p912ducking-Info.plist"; sourceTree = "<group>"; };
26+
C9592EBF1823107000CE45EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
27+
C9592EC41823107000CE45EA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
28+
C9592EE41823110800CE45EA /* test.aif */ = {isa = PBXFileReference; lastKnownFileType = file; path = test.aif; sourceTree = "<group>"; };
29+
/* End PBXFileReference section */
30+
31+
/* Begin PBXFrameworksBuildPhase section */
32+
C9592EA61823107000CE45EA /* Frameworks */ = {
33+
isa = PBXFrameworksBuildPhase;
34+
buildActionMask = 2147483647;
35+
files = (
36+
);
37+
runOnlyForDeploymentPostprocessing = 0;
38+
};
39+
/* End PBXFrameworksBuildPhase section */
40+
41+
/* Begin PBXGroup section */
42+
C9592EA01823107000CE45EA = {
43+
isa = PBXGroup;
44+
children = (
45+
C9592EB21823107000CE45EA /* ch27p912ducking */,
46+
C9592EAA1823107000CE45EA /* Products */,
47+
);
48+
sourceTree = "<group>";
49+
};
50+
C9592EAA1823107000CE45EA /* Products */ = {
51+
isa = PBXGroup;
52+
children = (
53+
C9592EA91823107000CE45EA /* ch27p912ducking.app */,
54+
);
55+
name = Products;
56+
sourceTree = "<group>";
57+
};
58+
C9592EB21823107000CE45EA /* ch27p912ducking */ = {
59+
isa = PBXGroup;
60+
children = (
61+
3280FA611997D07D00EA8B8B /* AppDelegate.swift */,
62+
C9592EBE1823107000CE45EA /* Main.storyboard */,
63+
3280FA5F1997C97700EA8B8B /* ViewController.swift */,
64+
3280FA5D1997C57900EA8B8B /* Player.swift */,
65+
C9592EE41823110800CE45EA /* test.aif */,
66+
C9592EC41823107000CE45EA /* Assets.xcassets */,
67+
3241C22C1BB5C6F300D09188 /* LaunchScreen.storyboard */,
68+
C9592EB41823107000CE45EA /* ch27p912ducking-Info.plist */,
69+
);
70+
path = ch27p912ducking;
71+
sourceTree = "<group>";
72+
};
73+
/* End PBXGroup section */
74+
75+
/* Begin PBXNativeTarget section */
76+
C9592EA81823107000CE45EA /* ch27p912ducking */ = {
77+
isa = PBXNativeTarget;
78+
buildConfigurationList = C9592EDB1823107100CE45EA /* Build configuration list for PBXNativeTarget "ch27p912ducking" */;
79+
buildPhases = (
80+
C9592EA51823107000CE45EA /* Sources */,
81+
C9592EA61823107000CE45EA /* Frameworks */,
82+
C9592EA71823107000CE45EA /* Resources */,
83+
);
84+
buildRules = (
85+
);
86+
dependencies = (
87+
);
88+
name = ch27p912ducking;
89+
productName = ch27p912ducking;
90+
productReference = C9592EA91823107000CE45EA /* ch27p912ducking.app */;
91+
productType = "com.apple.product-type.application";
92+
};
93+
/* End PBXNativeTarget section */
94+
95+
/* Begin PBXProject section */
96+
C9592EA11823107000CE45EA /* Project object */ = {
97+
isa = PBXProject;
98+
attributes = {
99+
LastSwiftUpdateCheck = 0700;
100+
LastUpgradeCheck = 0500;
101+
ORGANIZATIONNAME = "Matt Neuburg";
102+
TargetAttributes = {
103+
C9592EA81823107000CE45EA = {
104+
SystemCapabilities = {
105+
com.apple.BackgroundModes = {
106+
enabled = 0;
107+
};
108+
};
109+
};
110+
};
111+
};
112+
buildConfigurationList = C9592EA41823107000CE45EA /* Build configuration list for PBXProject "ch27p912ducking" */;
113+
compatibilityVersion = "Xcode 3.2";
114+
developmentRegion = English;
115+
hasScannedForEncodings = 0;
116+
knownRegions = (
117+
en,
118+
Base,
119+
);
120+
mainGroup = C9592EA01823107000CE45EA;
121+
productRefGroup = C9592EAA1823107000CE45EA /* Products */;
122+
projectDirPath = "";
123+
projectRoot = "";
124+
targets = (
125+
C9592EA81823107000CE45EA /* ch27p912ducking */,
126+
);
127+
};
128+
/* End PBXProject section */
129+
130+
/* Begin PBXResourcesBuildPhase section */
131+
C9592EA71823107000CE45EA /* Resources */ = {
132+
isa = PBXResourcesBuildPhase;
133+
buildActionMask = 2147483647;
134+
files = (
135+
C9592EC51823107000CE45EA /* Assets.xcassets in Resources */,
136+
3241C22D1BB5C6F300D09188 /* LaunchScreen.storyboard in Resources */,
137+
C9592EE51823110800CE45EA /* test.aif in Resources */,
138+
C9592EC01823107000CE45EA /* Main.storyboard in Resources */,
139+
);
140+
runOnlyForDeploymentPostprocessing = 0;
141+
};
142+
/* End PBXResourcesBuildPhase section */
143+
144+
/* Begin PBXSourcesBuildPhase section */
145+
C9592EA51823107000CE45EA /* Sources */ = {
146+
isa = PBXSourcesBuildPhase;
147+
buildActionMask = 2147483647;
148+
files = (
149+
3280FA601997C97700EA8B8B /* ViewController.swift in Sources */,
150+
3280FA5E1997C57900EA8B8B /* Player.swift in Sources */,
151+
3280FA621997D07D00EA8B8B /* AppDelegate.swift in Sources */,
152+
);
153+
runOnlyForDeploymentPostprocessing = 0;
154+
};
155+
/* End PBXSourcesBuildPhase section */
156+
157+
/* Begin PBXVariantGroup section */
158+
C9592EBE1823107000CE45EA /* Main.storyboard */ = {
159+
isa = PBXVariantGroup;
160+
children = (
161+
C9592EBF1823107000CE45EA /* Base */,
162+
);
163+
name = Main.storyboard;
164+
sourceTree = "<group>";
165+
};
166+
/* End PBXVariantGroup section */
167+
168+
/* Begin XCBuildConfiguration section */
169+
C9592ED91823107100CE45EA /* Debug */ = {
170+
isa = XCBuildConfiguration;
171+
buildSettings = {
172+
ALWAYS_SEARCH_USER_PATHS = NO;
173+
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
174+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
175+
CLANG_CXX_LIBRARY = "libc++";
176+
CLANG_ENABLE_MODULES = YES;
177+
CLANG_ENABLE_OBJC_ARC = YES;
178+
CLANG_WARN_BOOL_CONVERSION = YES;
179+
CLANG_WARN_CONSTANT_CONVERSION = YES;
180+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
181+
CLANG_WARN_EMPTY_BODY = YES;
182+
CLANG_WARN_ENUM_CONVERSION = YES;
183+
CLANG_WARN_INT_CONVERSION = YES;
184+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
185+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
186+
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
187+
COPY_PHASE_STRIP = NO;
188+
GCC_C_LANGUAGE_STANDARD = gnu99;
189+
GCC_DYNAMIC_NO_PIC = NO;
190+
GCC_OPTIMIZATION_LEVEL = 0;
191+
GCC_PREPROCESSOR_DEFINITIONS = (
192+
"DEBUG=1",
193+
"$(inherited)",
194+
);
195+
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
196+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
197+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
198+
GCC_WARN_UNDECLARED_SELECTOR = YES;
199+
GCC_WARN_UNINITIALIZED_AUTOS = YES;
200+
GCC_WARN_UNUSED_FUNCTION = YES;
201+
GCC_WARN_UNUSED_VARIABLE = YES;
202+
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
203+
ONLY_ACTIVE_ARCH = YES;
204+
SDKROOT = iphoneos;
205+
};
206+
name = Debug;
207+
};
208+
C9592EDA1823107100CE45EA /* Release */ = {
209+
isa = XCBuildConfiguration;
210+
buildSettings = {
211+
ALWAYS_SEARCH_USER_PATHS = NO;
212+
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
213+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
214+
CLANG_CXX_LIBRARY = "libc++";
215+
CLANG_ENABLE_MODULES = YES;
216+
CLANG_ENABLE_OBJC_ARC = YES;
217+
CLANG_WARN_BOOL_CONVERSION = YES;
218+
CLANG_WARN_CONSTANT_CONVERSION = YES;
219+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
220+
CLANG_WARN_EMPTY_BODY = YES;
221+
CLANG_WARN_ENUM_CONVERSION = YES;
222+
CLANG_WARN_INT_CONVERSION = YES;
223+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
224+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
225+
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
226+
COPY_PHASE_STRIP = YES;
227+
ENABLE_NS_ASSERTIONS = NO;
228+
GCC_C_LANGUAGE_STANDARD = gnu99;
229+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
230+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
231+
GCC_WARN_UNDECLARED_SELECTOR = YES;
232+
GCC_WARN_UNINITIALIZED_AUTOS = YES;
233+
GCC_WARN_UNUSED_FUNCTION = YES;
234+
GCC_WARN_UNUSED_VARIABLE = YES;
235+
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
236+
SDKROOT = iphoneos;
237+
VALIDATE_PRODUCT = YES;
238+
};
239+
name = Release;
240+
};
241+
C9592EDC1823107100CE45EA /* Debug */ = {
242+
isa = XCBuildConfiguration;
243+
buildSettings = {
244+
ARCHS = "$(ARCHS_STANDARD)";
245+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
246+
CLANG_ENABLE_MODULES = YES;
247+
GCC_PRECOMPILE_PREFIX_HEADER = YES;
248+
GCC_PREFIX_HEADER = "";
249+
INFOPLIST_FILE = "ch27p912ducking/ch27p912ducking-Info.plist";
250+
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
251+
ONLY_ACTIVE_ARCH = NO;
252+
PRODUCT_NAME = "$(TARGET_NAME)";
253+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
254+
TARGETED_DEVICE_FAMILY = "1,2";
255+
WRAPPER_EXTENSION = app;
256+
};
257+
name = Debug;
258+
};
259+
C9592EDD1823107100CE45EA /* Release */ = {
260+
isa = XCBuildConfiguration;
261+
buildSettings = {
262+
ARCHS = "$(ARCHS_STANDARD)";
263+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
264+
CLANG_ENABLE_MODULES = YES;
265+
GCC_PRECOMPILE_PREFIX_HEADER = YES;
266+
GCC_PREFIX_HEADER = "";
267+
INFOPLIST_FILE = "ch27p912ducking/ch27p912ducking-Info.plist";
268+
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
269+
ONLY_ACTIVE_ARCH = NO;
270+
PRODUCT_NAME = "$(TARGET_NAME)";
271+
TARGETED_DEVICE_FAMILY = "1,2";
272+
WRAPPER_EXTENSION = app;
273+
};
274+
name = Release;
275+
};
276+
/* End XCBuildConfiguration section */
277+
278+
/* Begin XCConfigurationList section */
279+
C9592EA41823107000CE45EA /* Build configuration list for PBXProject "ch27p912ducking" */ = {
280+
isa = XCConfigurationList;
281+
buildConfigurations = (
282+
C9592ED91823107100CE45EA /* Debug */,
283+
C9592EDA1823107100CE45EA /* Release */,
284+
);
285+
defaultConfigurationIsVisible = 0;
286+
defaultConfigurationName = Release;
287+
};
288+
C9592EDB1823107100CE45EA /* Build configuration list for PBXNativeTarget "ch27p912ducking" */ = {
289+
isa = XCConfigurationList;
290+
buildConfigurations = (
291+
C9592EDC1823107100CE45EA /* Debug */,
292+
C9592EDD1823107100CE45EA /* Release */,
293+
);
294+
defaultConfigurationIsVisible = 0;
295+
defaultConfigurationName = Release;
296+
};
297+
/* End XCConfigurationList section */
298+
};
299+
rootObject = C9592EA11823107000CE45EA /* Project object */;
300+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
2+
import UIKit
3+
import AVFoundation
4+
5+
@UIApplicationMain
6+
class AppDelegate : UIResponder, UIApplicationDelegate {
7+
var window : UIWindow?
8+
9+
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
10+
11+
// new in iOS 9, can check beforehand
12+
let ok = AVAudioSession.sharedInstance().availableCategories.contains(AVAudioSessionCategoryAmbient)
13+
print(ok)
14+
_ = try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, withOptions: [])
15+
16+
// deliberate leak here
17+
18+
NSNotificationCenter.defaultCenter().addObserverForName(
19+
AVAudioSessionRouteChangeNotification, object: nil, queue: nil) {
20+
(note:NSNotification!) in
21+
print("change route \(note.userInfo)")
22+
print("current route \(AVAudioSession.sharedInstance().currentRoute)")
23+
}
24+
// properly, if the route changes from some kind of Headphones to Built-In Speaker,
25+
// we should pause our sound (doesn't happen automatically)
26+
27+
NSNotificationCenter.defaultCenter().addObserverForName(
28+
AVAudioSessionInterruptionNotification, object: nil, queue: nil) {
29+
(n:NSNotification) in
30+
guard let why =
31+
n.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt
32+
else {return}
33+
guard let type = AVAudioSessionInterruptionType(rawValue: why)
34+
else {return}
35+
if type == .Began {
36+
print("interruption began:\n\(n.userInfo!)")
37+
} else {
38+
print("interruption ended:\n\(n.userInfo!)")
39+
guard let opt = n.userInfo![AVAudioSessionInterruptionOptionKey] as? UInt else {return}
40+
let opts = AVAudioSessionInterruptionOptions(rawValue: opt)
41+
if opts.contains(.ShouldResume) {
42+
print("should resume")
43+
} else {
44+
print("not should resume")
45+
}
46+
}
47+
}
48+
49+
// use control center to test, e.g. start and stop a Music song
50+
51+
NSNotificationCenter.defaultCenter().addObserverForName(
52+
AVAudioSessionSilenceSecondaryAudioHintNotification, object: nil, queue: nil) {
53+
(n:NSNotification) in
54+
guard let why = n.userInfo?[AVAudioSessionSilenceSecondaryAudioHintTypeKey] as? UInt else {return}
55+
guard let type = AVAudioSessionSilenceSecondaryAudioHintType(rawValue:why) else {return}
56+
if type == .Begin {
57+
print("silence hint begin:\n\(n.userInfo!)")
58+
} else {
59+
print("silence hint end:\n\(n.userInfo!)")
60+
}
61+
}
62+
63+
64+
return true
65+
}
66+
67+
func applicationDidBecomeActive(application: UIApplication) {
68+
print("app became active")
69+
_ = try? AVAudioSession.sharedInstance().setActive(true, withOptions: [])
70+
}
71+
72+
func applicationWillResignActive(application: UIApplication) {
73+
print("app will resign active")
74+
}
75+
76+
func applicationDidEnterBackground(application: UIApplication) {
77+
print("app did enter background")
78+
}
79+
}

0 commit comments

Comments
 (0)