Int {
14 | return self.count > 0 ? self.count - 1 : 0
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 | on: [push]
3 |
4 | jobs:
5 | build:
6 | name: Build
7 | runs-on: macOS-latest
8 | steps:
9 | - uses: actions/checkout@v1
10 | - name: Build
11 | run: swift build -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios12.1-simulator"
12 | working-directory: ./
13 |
--------------------------------------------------------------------------------
/Sources/KKCarPlayManagerExtensions/KKStaticContainerItemExtension.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import KKCarPlayManager
3 |
4 | /// :nodoc:
5 | extension KKStaticContainerItem {
6 | /// :nodoc:
7 | public convenience init(identifier: String, title: String, @KKCarPlayItemsBuilder builder:()->[KKBasicContentItem]) {
8 | self.init(identifier:identifier, title: title, children:builder())
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/Example/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - KKCarPlayManager (0.1.0):
3 | - KKCarPlayManager/KKCarPlayManager (= 0.1.0)
4 | - KKCarPlayManager/KKCarPlayManager (0.1.0)
5 |
6 | DEPENDENCIES:
7 | - KKCarPlayManager (from `../`)
8 |
9 | EXTERNAL SOURCES:
10 | KKCarPlayManager:
11 | :path: "../"
12 |
13 | SPEC CHECKSUMS:
14 | KKCarPlayManager: 30a1830b2902b62dac1ff28d4f31184365897f7a
15 |
16 | PODFILE CHECKSUM: fc55f97309a5993266f2ac5262bab1b28ae05619
17 |
18 | COCOAPODS: 1.7.4
19 |
--------------------------------------------------------------------------------
/Tests/KKCarPlayManagerTests/KKCarPlayManagerTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import KKCarPlayManager
3 |
4 | final class KKCarPlayManagerTests: XCTestCase {
5 | func testExample() {
6 | // This is an example of a functional test case.
7 | // Use XCTAssert and related functions to verify your tests produce the correct
8 | // results.
9 | // XCTAssertEqual(KKCarPlayManager().text, "Hello, World!")
10 | }
11 |
12 | static var allTests = [
13 | ("testExample", testExample),
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/Package@swift-4.2.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:4.2
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "KKCarPlayManager",
7 | platforms: [ .iOS(.v8) ],
8 | products: [
9 | .library(
10 | name: "KKCarPlayManager",
11 | targets: ["KKCarPlayManager"]),
12 | ],
13 | dependencies: [
14 | // .package(url: /* package url */, from: "1.0.0"),
15 | ],
16 | targets: [
17 | .target(
18 | name: "KKCarPlayManager",
19 | dependencies: []),
20 | .testTarget(
21 | name: "KKCarPlayManagerTests",
22 | dependencies: ["KKCarPlayManager"]),
23 | ],
24 | swiftLanguageVersions: [.v4, .v4_2, .v5]
25 | )
26 |
--------------------------------------------------------------------------------
/Package@swift-5.0.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.0
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "KKCarPlayManager",
7 | platforms: [ .iOS(.v8) ],
8 | products: [
9 | .library(
10 | name: "KKCarPlayManager",
11 | targets: ["KKCarPlayManager"]),
12 | ],
13 | dependencies: [
14 | // .package(url: /* package url */, from: "1.0.0"),
15 | ],
16 | targets: [
17 | .target(
18 | name: "KKCarPlayManager",
19 | dependencies: []),
20 | .testTarget(
21 | name: "KKCarPlayManagerTests",
22 | dependencies: ["KKCarPlayManager"]),
23 | ],
24 | swiftLanguageVersions: [.v4, .v4_2, .v5]
25 | )
26 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | com.jazzy.kkcarplaymanager
7 | CFBundleName
8 | KKCarPlayManager
9 | DocSetPlatformFamily
10 | kkcarplaymanager
11 | isDashDocset
12 |
13 | dashIndexFilePath
14 | index.html
15 | isJavaScriptEnabled
16 |
17 | DashDocSetFamily
18 | dashtoc
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Sources/KKCarPlayManager/KKStaticContainerItem.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | /// A container item with static children.
4 | public class KKStaticContainerItem: KKBasicContentItem {
5 |
6 | private var staticChildren: [KKBasicContentItem]
7 |
8 | /// Creates an instance.
9 | ///
10 | /// - Parameter identifier: Identifier of the item.
11 | /// - Parameter title: Title of the item.
12 | /// - Parameter children: Children of the item.
13 | public init(identifier: String, title: String, children: [KKBasicContentItem]) {
14 | self.staticChildren = children
15 | super.init(identifier: identifier)
16 | self.title = title
17 | self.children = children
18 | isPlayable = false
19 | isContainer = true
20 | }
21 |
22 | /// :nodoc:
23 | public override func loadChildren(callback: @escaping (Error?) -> Void) throws {
24 | self.children = self.staticChildren
25 | callback(nil)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "KKCarPlayManager",
7 | platforms: [ .iOS(.v8) ],
8 | products: [
9 | .library(
10 | name: "KKCarPlayManager",
11 | targets: ["KKCarPlayManager"]),
12 | .library(
13 | name: "KKCarPlayManagerExtension",
14 | targets: ["KKCarPlayManagerExtensions"]),
15 | ],
16 | dependencies: [
17 | // .package(url: /* package url */, from: "1.0.0"),
18 | ],
19 | targets: [
20 | .target(
21 | name: "KKCarPlayManager",
22 | dependencies: []),
23 | .target(
24 | name: "KKCarPlayManagerExtensions",
25 | dependencies: ["KKCarPlayManager"]),
26 | .testTarget(
27 | name: "KKCarPlayManagerTests",
28 | dependencies: ["KKCarPlayManager"]),
29 | ],
30 | swiftLanguageVersions: [.v4, .v4_2, .v5]
31 | )
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 KKBOX
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/KKCarPlayManager.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'KKCarPlayManager'
3 | s.version = '0.1.3'
4 | s.summary = 'Helps to implement an CarPlay audio app.'
5 | s.description = <<-DESC
6 | KKCarPlayManager helps you to build the tree of the content items to let users to browsw on a CarPlay audio app.
7 | DESC
8 |
9 | s.homepage = 'https://github.com/KKBOX/KKCarPlayManager'
10 | s.license = { :type => 'MIT', :file => 'LICENSE' }
11 | s.author = { 'zonble' => 'zonble@gmail.com' }
12 | s.source = { :git => 'https://github.com/KKBOX/KKCarPlayManager.git', :tag => s.version.to_s }
13 |
14 | s.ios.deployment_target = '8.0'
15 | s.swift_versions = ['4.2', '5.0', '5.1']
16 |
17 | s.subspec 'KKCarPlayManager' do |sp|
18 | sp.source_files = 'Sources/KKCarPlayManager/**/*'
19 | end
20 |
21 | s.subspec 'KKCarPlayManagerExtensions' do |sp|
22 | sp.source_files = 'Sources/KKCarPlayManagerExtensions/**/*'
23 | sp.dependency 'KKCarPlayManager/KKCarPlayManager'
24 | end
25 |
26 | s.frameworks = 'MediaPlayer'
27 | s.default_subspec = 'KKCarPlayManager'
28 |
29 | end
30 |
--------------------------------------------------------------------------------
/docs/badge.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | documentation
17 |
18 |
19 | documentation
20 |
21 |
22 | 100%
23 |
24 |
25 | 100%
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/badge.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | documentation
17 |
18 |
19 | documentation
20 |
21 |
22 | 100%
23 |
24 |
25 | 100%
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Example/Example/PlayItem.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import KKCarPlayManager
3 | import AVFoundation
4 | import MediaPlayer
5 |
6 | enum PlayItemError: Error {
7 | case noURL
8 | }
9 |
10 | class PlayItem: KKBasicContentItem {
11 |
12 | var url: URL?
13 |
14 | public init(identifier: String, title: String, url urlString: String) {
15 | super.init(identifier: identifier)
16 | self.title = title
17 | url = URL(string: urlString)
18 | isContainer = false
19 | isPlayable = true
20 | }
21 |
22 | override func play(callback: @escaping (Error?) -> Void) throws -> Bool {
23 | guard let url = url else {
24 | callback(PlayItemError.noURL)
25 | return false
26 | }
27 | appDelegate().player.replaceCurrentItem(with: AVPlayerItem(url: url))
28 | appDelegate().player.play()
29 | MPNowPlayingInfoCenter.default().nowPlayingInfo = [
30 | MPNowPlayingInfoPropertyPlaybackRate: 1,
31 | MPMediaItemPropertyTitle: self.title ?? "",
32 | MPMediaItemPropertyArtist: "zonble",
33 | MPMediaItemPropertyAlbumTitle: "zonble",
34 | MPNowPlayingInfoPropertyElapsedPlaybackTime: 0,
35 | MPMediaItemPropertyPlaybackDuration: 100,
36 | MPNowPlayingInfoPropertyPlaybackQueueCount: 1,
37 | MPNowPlayingInfoPropertyPlaybackQueueIndex: 0
38 | ]
39 | callback(nil)
40 | return true
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Sources/KKCarPlayManager/KKBasicContentItem.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import MediaPlayer
3 |
4 | /// KKBOX's own subclass of MPContentItem.
5 | ///
6 | /// Please subclass the class and override `loadChildren(callback:)` or
7 | /// `play(callback:)` for your own need.
8 | open class KKBasicContentItem: MPContentItem {
9 |
10 | /// Childten items of the item. We use this property to build a tree and
11 | /// feed item on each index path to MPPlayableContentManager.
12 | open var children: [KKBasicContentItem]?
13 |
14 | /// To load the children of the node.
15 | ///
16 | /// - Parameters:
17 | /// - callback: the callback function. It contains an error object if it
18 | /// encounters any error while loading.
19 | open func loadChildren(callback: @escaping (Error?) -> Void) throws {
20 | if self.isContainer == false {
21 | fatalError("Not a container.")
22 | }
23 | fatalError("Not implemented.")
24 | }
25 |
26 | /// To play the media mapping to the item.
27 | open func play(callback: @escaping (Error?) -> Void) throws -> Bool {
28 | fatalError("Not implemented")
29 | }
30 | }
31 |
32 | extension KKBasicContentItem {
33 |
34 | /// Apply an image to the current item.
35 | public func apply(image: UIImage?) -> Self {
36 | if let image = image {
37 | self.artwork = MPMediaItemArtwork(image: image)
38 | } else {
39 | self.artwork = nil
40 | }
41 | return self
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/docs/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | // On doc load, toggle the URL hash discussion if present
12 | $(document).ready(function() {
13 | if (!window.jazzy.docset) {
14 | var linkToHash = $('a[href="' + window.location.hash +'"]');
15 | linkToHash.trigger("click");
16 | }
17 | });
18 |
19 | // On token click, toggle its discussion and animate token.marginLeft
20 | $(".token").click(function(event) {
21 | if (window.jazzy.docset) {
22 | return;
23 | }
24 | var link = $(this);
25 | var animationDuration = 300;
26 | var tokenOffset = "15px";
27 | var original = link.css('marginLeft') == tokenOffset;
28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration);
29 | $content = link.parent().parent().next();
30 | $content.slideToggle(animationDuration);
31 |
32 | // Keeps the document from jumping to the hash.
33 | var href = $(this).attr('href');
34 | if (history.pushState) {
35 | history.pushState({}, '', href);
36 | } else {
37 | location.hash = href;
38 | }
39 | event.preventDefault();
40 | });
41 |
42 | // Dumb down quotes within code blocks that delimit strings instead of quotations
43 | // https://github.com/realm/jazzy/issues/714
44 | $("code q").replaceWith(function () {
45 | return ["\"", $(this).contents(), "\""];
46 | });
47 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | // On doc load, toggle the URL hash discussion if present
12 | $(document).ready(function() {
13 | if (!window.jazzy.docset) {
14 | var linkToHash = $('a[href="' + window.location.hash +'"]');
15 | linkToHash.trigger("click");
16 | }
17 | });
18 |
19 | // On token click, toggle its discussion and animate token.marginLeft
20 | $(".token").click(function(event) {
21 | if (window.jazzy.docset) {
22 | return;
23 | }
24 | var link = $(this);
25 | var animationDuration = 300;
26 | var tokenOffset = "15px";
27 | var original = link.css('marginLeft') == tokenOffset;
28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration);
29 | $content = link.parent().parent().next();
30 | $content.slideToggle(animationDuration);
31 |
32 | // Keeps the document from jumping to the hash.
33 | var href = $(this).attr('href');
34 | if (history.pushState) {
35 | history.pushState({}, '', href);
36 | } else {
37 | location.hash = href;
38 | }
39 | event.preventDefault();
40 | });
41 |
42 | // Dumb down quotes within code blocks that delimit strings instead of quotations
43 | // https://github.com/realm/jazzy/issues/714
44 | $("code q").replaceWith(function () {
45 | return ["\"", $(this).contents(), "\""];
46 | });
47 |
--------------------------------------------------------------------------------
/Example/Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIBackgroundModes
24 |
25 | audio
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Example/Example/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Example/Example/ViewController.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import AVFoundation
3 | import MediaPlayer
4 |
5 | typealias PlayableItem = (String, String)
6 |
7 | class ViewController: UITableViewController {
8 | var items:[[PlayableItem]] = [
9 | [
10 | ("天狗", "https://zonble.net/MIDI/tiengo.mp3"),
11 | ("回向", "https://zonble.net/MIDI/return.mp3")],
12 | [
13 | ("orz", "https://zonble.net/MIDI/orz.mp3"),
14 | ("藿香薊", "https://zonble.net/MIDI/ageratum_conyzoides.mp3")]
15 | ]
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 | self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
20 | self.title = "KKCarPlayManager Example"
21 | }
22 |
23 | override func numberOfSections(in tableView: UITableView) -> Int {
24 | return items.count
25 | }
26 |
27 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
28 | return items[section].count
29 | }
30 |
31 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
32 | let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
33 | cell.textLabel?.text = items[indexPath.section][indexPath.row].0
34 | return cell
35 | }
36 |
37 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
38 | tableView.deselectRow(at: indexPath, animated: true)
39 | let urlString = items[indexPath.section][indexPath.row].1
40 | let name = items[indexPath.section][indexPath.row].0
41 | if let url = URL(string: urlString) {
42 | appDelegate().player.replaceCurrentItem(with: AVPlayerItem(url: url))
43 | appDelegate().player.play()
44 | MPNowPlayingInfoCenter.default().nowPlayingInfo = [
45 | MPNowPlayingInfoPropertyPlaybackRate: 1,
46 | MPMediaItemPropertyTitle: name,
47 | MPMediaItemPropertyArtist: "zonble",
48 | MPMediaItemPropertyAlbumTitle: "zonble",
49 | MPNowPlayingInfoPropertyElapsedPlaybackTime: 0,
50 | MPMediaItemPropertyPlaybackDuration: 100,
51 | MPNowPlayingInfoPropertyPlaybackQueueCount: 1,
52 | MPNowPlayingInfoPropertyPlaybackQueueIndex: 0
53 | ]
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Example/Example/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import KKCarPlayManager
3 | import MediaPlayer
4 | import AVFoundation
5 |
6 | func appDelegate() -> AppDelegate {
7 | return UIApplication.shared.delegate as! AppDelegate
8 | }
9 |
10 | @UIApplicationMain
11 | class AppDelegate: UIResponder, UIApplicationDelegate {
12 | var window: UIWindow?
13 | var manager: KKCarPlayManager?
14 | var player = AVPlayer()
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 |
18 | MPRemoteCommandCenter.shared().playCommand.addTarget { event in
19 | return .success
20 | }
21 | MPRemoteCommandCenter.shared().pauseCommand.addTarget { event in
22 | return .success
23 | }
24 | MPRemoteCommandCenter.shared().stopCommand.addTarget { event in
25 | return .success
26 | }
27 | MPRemoteCommandCenter.shared().togglePlayPauseCommand.addTarget { event in
28 | return .success
29 | }
30 | MPRemoteCommandCenter.shared().previousTrackCommand.addTarget { event in
31 | return .success
32 | }
33 | MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { event in
34 | return .success
35 | }
36 | application.beginReceivingRemoteControlEvents()
37 |
38 |
39 | let rooNode = KKStaticContainerItem(identifier: "root", title: "Root", children: [
40 | KKStaticContainerItem(identifier: "folder1", title: "Folder 1", children: [
41 | PlayItem(identifier: "Song_1_1", title: "天狗", url: "https://zonble.net/MIDI/tiengo.mp3"),
42 | PlayItem(identifier: "Song_1_2", title: "回向", url: "https://zonble.net/MIDI/return.mp3"),
43 | ]),
44 | KKStaticContainerItem(identifier: "folder_2", title: "Folder 2", children: [
45 | PlayItem(identifier: "Song_2_1", title: "orz", url: "https://zonble.net/MIDI/orz.mp3"),
46 | PlayItem(identifier: "Song_2_2", title: "藿香薊", url: "https://zonble.net/MIDI/ageratum_conyzoides.mp3")
47 | ]),
48 | ]
49 | )
50 | manager = KKCarPlayManager(rootNode: rooNode)
51 | manager?.activate()
52 |
53 | try? AVAudioSession.sharedInstance().setCategory(.playback)
54 | try? AVAudioSession.sharedInstance().setActive(true, options: [])
55 |
56 | let vc = ViewController(style: .grouped)
57 | let nav = UINavigationController(rootViewController: vc)
58 | window = UIWindow(frame: UIScreen.main.bounds)
59 | window?.rootViewController = nav
60 | window?.makeKeyAndVisible()
61 |
62 | return true
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/docs/search.json:
--------------------------------------------------------------------------------
1 | {"Enums/KKCarPlayManagerError.html#/s:16KKCarPlayManager0abC5ErrorO12itemNotExistyA2CmF":{"name":"itemNotExist","abstract":"The item does not exist.
","parent_name":"KKCarPlayManagerError"},"Enums/KKCarPlayManagerError.html#/s:16KKCarPlayManager0abC5ErrorO7messageyACSScACmF":{"name":"message(_:)","abstract":"An error with a message.
","parent_name":"KKCarPlayManagerError"},"Enums/KKCarPlayManagerError.html":{"name":"KKCarPlayManagerError","abstract":"The error used in KKCarPlayManager .
"},"Classes/KKStaticContainerItem.html#/s:16KKCarPlayManager21KKStaticContainerItemC10identifier5title8childrenACSS_SSSayAA014KKBasicContentF0CGtcfc":{"name":"init(identifier:title:children:)","abstract":"Creates an instance.
","parent_name":"KKStaticContainerItem"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC8activateyyF":{"name":"activate()","abstract":"Set the data source and delegate of MPPlayableContentManager to","parent_name":"KKCarPlayManager"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC10deactivateyyF":{"name":"deactivate()","abstract":"
Set the data source and delegate of MPPlayableContentManager to nil.
","parent_name":"KKCarPlayManager"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC8rootNodeAbA18KKBasicContentItemC_tcfc":{"name":"init(rootNode:)","abstract":"Creates a new instance.
","parent_name":"KKCarPlayManager"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC8childrenSayACGSgvp":{"name":"children","abstract":"Childten items of the item. We use this property to build a tree and","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC12loadChildren8callbackyys5Error_pSgc_tKF":{"name":"loadChildren(callback:)","abstract":"
To load the children of the node.
","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC4play8callbackSbys5Error_pSgc_tKF":{"name":"play(callback:)","abstract":"To play the media mapping to the item.
","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC5apply5imageACSo7UIImageCSg_tF":{"name":"apply(image:)","abstract":"Apply an image to the current item.
","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html":{"name":"KKBasicContentItem","abstract":"KKBOX’s own subclass of MPContentItem.
"},"Classes/KKCarPlayManager.html":{"name":"KKCarPlayManager","abstract":"A class helps your to build a tree structure of playable items for CarPlay.
"},"Classes/KKStaticContainerItem.html":{"name":"KKStaticContainerItem","abstract":"A container item with static children.
"},"Classes.html":{"name":"Classes","abstract":"The following classes are available globally.
"},"Enums.html":{"name":"Enumerations","abstract":"The following enumerations are available globally.
"}}
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/search.json:
--------------------------------------------------------------------------------
1 | {"Enums/KKCarPlayManagerError.html#/s:16KKCarPlayManager0abC5ErrorO12itemNotExistyA2CmF":{"name":"itemNotExist","abstract":"The item does not exist.
","parent_name":"KKCarPlayManagerError"},"Enums/KKCarPlayManagerError.html#/s:16KKCarPlayManager0abC5ErrorO7messageyACSScACmF":{"name":"message(_:)","abstract":"An error with a message.
","parent_name":"KKCarPlayManagerError"},"Enums/KKCarPlayManagerError.html":{"name":"KKCarPlayManagerError","abstract":"The error used in KKCarPlayManager .
"},"Classes/KKStaticContainerItem.html#/s:16KKCarPlayManager21KKStaticContainerItemC10identifier5title8childrenACSS_SSSayAA014KKBasicContentF0CGtcfc":{"name":"init(identifier:title:children:)","abstract":"Creates an instance.
","parent_name":"KKStaticContainerItem"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC8activateyyF":{"name":"activate()","abstract":"Set the data source and delegate of MPPlayableContentManager to","parent_name":"KKCarPlayManager"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC10deactivateyyF":{"name":"deactivate()","abstract":"
Set the data source and delegate of MPPlayableContentManager to nil.
","parent_name":"KKCarPlayManager"},"Classes/KKCarPlayManager.html#/s:16KKCarPlayManagerAAC8rootNodeAbA18KKBasicContentItemC_tcfc":{"name":"init(rootNode:)","abstract":"Creates a new instance.
","parent_name":"KKCarPlayManager"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC8childrenSayACGSgvp":{"name":"children","abstract":"Childten items of the item. We use this property to build a tree and","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC12loadChildren8callbackyys5Error_pSgc_tKF":{"name":"loadChildren(callback:)","abstract":"
To load the children of the node.
","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC4play8callbackSbys5Error_pSgc_tKF":{"name":"play(callback:)","abstract":"To play the media mapping to the item.
","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html#/s:16KKCarPlayManager18KKBasicContentItemC5apply5imageACSo7UIImageCSg_tF":{"name":"apply(image:)","abstract":"Apply an image to the current item.
","parent_name":"KKBasicContentItem"},"Classes/KKBasicContentItem.html":{"name":"KKBasicContentItem","abstract":"KKBOX’s own subclass of MPContentItem.
"},"Classes/KKCarPlayManager.html":{"name":"KKCarPlayManager","abstract":"A class helps your to build a tree structure of playable items for CarPlay.
"},"Classes/KKStaticContainerItem.html":{"name":"KKStaticContainerItem","abstract":"A container item with static children.
"},"Classes.html":{"name":"Classes","abstract":"The following classes are available globally.
"},"Enums.html":{"name":"Enumerations","abstract":"The following enumerations are available globally.
"}}
--------------------------------------------------------------------------------
/docs/Extensions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Extensions Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | Extensions Reference
25 |
26 |
27 |
28 |
70 |
71 |
72 |
73 | Extensions
74 | The following extensions are available globally.
75 |
76 |
77 |
102 |
103 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/docs/Enums.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Enumerations Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | Enumerations Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | Enumerations
58 | The following enumerations are available globally.
59 |
60 |
61 |
62 |
63 |
64 |
65 |
72 |
73 |
74 |
75 |
76 |
81 |
82 |
Declaration
83 |
84 |
Swift
85 |
public enum KKCarPlayManagerError : Error , LocalizedError
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Extensions.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Extensions Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | Extensions Reference
25 |
26 |
27 |
28 |
70 |
71 |
72 |
73 | Extensions
74 | The following extensions are available globally.
75 |
76 |
77 |
102 |
103 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Enums.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Enumerations Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | Enumerations Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | Enumerations
58 | The following enumerations are available globally.
59 |
60 |
61 |
62 |
63 |
64 |
65 |
72 |
73 |
74 |
75 |
76 |
81 |
82 |
Declaration
83 |
84 |
Swift
85 |
public enum KKCarPlayManagerError : Error , LocalizedError
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/docs/Structs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Structures Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | Structures Reference
25 |
26 |
27 |
28 |
70 |
71 |
72 |
73 | Structures
74 | The following structures are available globally.
75 |
76 |
77 |
78 |
79 |
80 |
81 |
88 |
89 |
90 |
91 |
92 |
93 |
Undocumented
94 |
95 |
See more
96 |
97 |
98 |
Declaration
99 |
100 |
Swift
101 |
public struct KKCarPlayItemsBuilder
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
116 |
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Structs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Structures Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | Structures Reference
25 |
26 |
27 |
28 |
70 |
71 |
72 |
73 | Structures
74 | The following structures are available globally.
75 |
76 |
77 |
78 |
79 |
80 |
81 |
88 |
89 |
90 |
91 |
92 |
93 |
Undocumented
94 |
95 |
See more
96 |
97 |
98 |
Declaration
99 |
100 |
Swift
101 |
public struct KKCarPlayItemsBuilder
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
116 |
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/docs/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/Sources/KKCarPlayManager/KKCarPlayManager.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import MediaPlayer
3 |
4 | /// The error used in `KKCarPlayManager`.
5 | public enum KKCarPlayManagerError : Error, LocalizedError {
6 | /// The item does not exist.
7 | case itemNotExist
8 | /// An error with a message.
9 | case message(String)
10 |
11 | /// :nodoc:
12 | public var errorDescription: String? {
13 | switch self {
14 | case .itemNotExist:
15 | return "The item does not exist."
16 | case .message(let message):
17 | return message
18 | }
19 | }
20 | }
21 |
22 | /// A class helps your to build a tree structure of playable items for CarPlay.
23 | public class KKCarPlayManager: NSObject {
24 |
25 | /// Set the data source and delegate of MPPlayableContentManager to
26 | /// the current instance of KKCarPlayManager.
27 | public func activate() {
28 | MPPlayableContentManager.shared().dataSource = self
29 | MPPlayableContentManager.shared().delegate = self
30 | MPPlayableContentManager.shared().beginUpdates()
31 | MPPlayableContentManager.shared().endUpdates()
32 | }
33 |
34 | /// Set the data source and delegate of MPPlayableContentManager to nil.
35 | public func deactivate() {
36 | MPPlayableContentManager.shared().dataSource = nil
37 | MPPlayableContentManager.shared().delegate = nil
38 | }
39 |
40 | /// The root node of KKCarPlayManager.
41 | public final var rootNode: KKBasicContentItem {
42 | didSet {
43 | MPPlayableContentManager.shared().beginUpdates()
44 | MPPlayableContentManager.shared().endUpdates()
45 | }
46 | }
47 | final var currentPlaybackCallback: ((Error?) -> Void)?
48 |
49 | /// Creates a new instance.
50 | /// - Parameter rootNode: The root node.
51 | public init(rootNode: KKBasicContentItem) {
52 | self.rootNode = rootNode
53 | super.init()
54 | }
55 |
56 |
57 | /// Travel through the tree to find a specific node by giving the
58 | /// index path of the node.
59 | ///
60 | /// - parameter indexPath: Index path of the node.
61 | /// - returns: The node found in the tree.
62 | fileprivate func travel(_ indexPath: IndexPath) -> KKBasicContentItem? {
63 | if indexPath.count == 0 {
64 | return self.rootNode
65 | }
66 | var node: KKBasicContentItem? = self.rootNode
67 | for i in 0.. Bool {
76 | let error = KKCarPlayManagerError.message(message)
77 | return self.commitCurrentPlaybackCallback(error)
78 | }
79 |
80 | /// :nodoc:
81 | @objc public final func commitCurrentPlaybackCallback(_ error: Error?) -> Bool {
82 | NSObject.cancelPreviousPerformRequests(withTarget: self)
83 | if let callback = currentPlaybackCallback {
84 | DispatchQueue.global(qos: .default).async {
85 | callback(error)
86 | }
87 | currentPlaybackCallback = nil
88 | return true
89 | }
90 | return false
91 | }
92 |
93 | /// :nodoc:
94 | public final func delayedCommitCurrentPlaybackCallbackWithourError() {
95 | NSObject.cancelPreviousPerformRequests(withTarget: self)
96 | self.perform(#selector(KKCarPlayManager.commitCurrentPlaybackCallback(_:)), with: nil, afterDelay: 0.5)
97 | }
98 |
99 | }
100 |
101 | extension KKCarPlayManager: MPPlayableContentDataSource {
102 | /// :nodoc:
103 | public final func numberOfChildItems(at indexPath: IndexPath) -> Int {
104 | let node = self.travel(indexPath)
105 | return node?.children?.count ?? 0
106 | }
107 |
108 | /// :nodoc:
109 | public final func contentItem(at indexPath: IndexPath) -> MPContentItem? {
110 | let node = self.travel(indexPath)
111 | return node
112 | }
113 |
114 | /// :nodoc:
115 | @objc(beginLoadingChildItemsAtIndexPath:completionHandler:)
116 | public final func beginLoadingChildItems(at indexPath: IndexPath, completionHandler: @escaping (Error?) -> ()) {
117 | func continueLoadingChildren() {
118 | guard let node = self.travel(indexPath) else {
119 | completionHandler(KKCarPlayManagerError.itemNotExist)
120 | return
121 | }
122 | if node.children != nil {
123 | for item in node.children! {
124 | item.children = nil
125 | }
126 | completionHandler(nil)
127 | return
128 | }
129 |
130 | do {
131 | try node.loadChildren { error in
132 | if let error = error {
133 | completionHandler(error)
134 | return
135 | }
136 | completionHandler(nil)
137 | }
138 | } catch {
139 | completionHandler(node.children != nil ? nil : error)
140 | }
141 | }
142 |
143 | continueLoadingChildren()
144 | }
145 |
146 | }
147 |
148 | extension KKCarPlayManager: MPPlayableContentDelegate {
149 | /// :nodoc:
150 | public final func playableContentManager(_ contentManager: MPPlayableContentManager, initiatePlaybackOfContentItemAt indexPath: IndexPath, completionHandler: @escaping (Error?) -> Void) {
151 | DispatchQueue.main.async { [weak self] in
152 | if let strongSelf = self {
153 | NSObject.cancelPreviousPerformRequests(withTarget: strongSelf)
154 | }
155 | guard let currentNode = self?.travel(indexPath) else {
156 | completionHandler(KKCarPlayManagerError.itemNotExist)
157 | return
158 | }
159 |
160 | self?.currentPlaybackCallback?(nil)
161 | self?.currentPlaybackCallback = completionHandler
162 | do {
163 | let shouldCleanCachedCallback = try currentNode.play(callback: completionHandler)
164 | if shouldCleanCachedCallback {
165 | self?.currentPlaybackCallback = nil
166 | }
167 | } catch {
168 | self?.currentPlaybackCallback?(error as NSError)
169 | self?.currentPlaybackCallback = nil
170 | }
171 | }
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/docs/Extensions/KKStaticContainerItem.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKStaticContainerItem Extension Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKStaticContainerItem Extension Reference
25 |
26 |
27 |
28 |
70 |
71 |
72 |
73 | KKStaticContainerItem
74 |
75 |
76 |
77 |
78 |
79 |
80 |
87 |
88 |
89 |
90 |
91 |
92 |
Undocumented
93 |
94 |
95 |
96 |
Declaration
97 |
98 |
Swift
99 |
public convenience init ( identifier : String , title : String , builder : () -> [ KKBasicContentItem ])
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Extensions/KKStaticContainerItem.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKStaticContainerItem Extension Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKStaticContainerItem Extension Reference
25 |
26 |
27 |
28 |
70 |
71 |
72 |
73 | KKStaticContainerItem
74 |
75 |
76 |
77 |
78 |
79 |
80 |
87 |
88 |
89 |
90 |
91 |
92 |
Undocumented
93 |
94 |
95 |
96 |
Declaration
97 |
98 |
Swift
99 |
public convenience init ( identifier : String , title : String , builder : () -> [ KKBasicContentItem ])
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/docs/Structs/KKCarPlayItemsBuilder.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKCarPlayItemsBuilder Structure Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKCarPlayItemsBuilder Structure Reference
25 |
26 |
27 |
28 |
70 |
71 |
72 |
73 | KKCarPlayItemsBuilder
74 |
75 |
76 |
public struct KKCarPlayItemsBuilder
77 |
78 |
79 |
80 | Undocumented
81 |
82 |
83 |
84 |
85 |
86 |
87 |
94 |
95 |
96 |
97 |
98 |
99 |
Undocumented
100 |
101 |
102 |
103 |
Declaration
104 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Structs/KKCarPlayItemsBuilder.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKCarPlayItemsBuilder Structure Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKCarPlayItemsBuilder Structure Reference
25 |
26 |
27 |
28 |
70 |
71 |
72 |
73 | KKCarPlayItemsBuilder
74 |
75 |
76 |
public struct KKCarPlayItemsBuilder
77 |
78 |
79 |
80 | Undocumented
81 |
82 |
83 |
84 |
85 |
86 |
87 |
94 |
95 |
96 |
97 |
98 |
99 |
Undocumented
100 |
101 |
102 |
103 |
Declaration
104 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/docs/Enums/KKCarPlayManagerError.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKCarPlayManagerError Enumeration Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKCarPlayManagerError Enumeration Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | KKCarPlayManagerError
58 |
59 |
60 |
public enum KKCarPlayManagerError : Error , LocalizedError
61 |
62 |
63 |
64 | The error used in KKCarPlayManager .
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
The item does not exist.
84 |
85 |
86 |
87 |
Declaration
88 |
89 |
Swift
90 |
case itemNotExist
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
105 |
106 |
107 |
108 |
109 |
110 |
An error with a message.
111 |
112 |
113 |
114 |
Declaration
115 |
116 |
Swift
117 |
case message ( String )
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
132 |
133 |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Enums/KKCarPlayManagerError.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKCarPlayManagerError Enumeration Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKCarPlayManagerError Enumeration Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | KKCarPlayManagerError
58 |
59 |
60 |
public enum KKCarPlayManagerError : Error , LocalizedError
61 |
62 |
63 |
64 | The error used in KKCarPlayManager .
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
The item does not exist.
84 |
85 |
86 |
87 |
Declaration
88 |
89 |
Swift
90 |
case itemNotExist
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
105 |
106 |
107 |
108 |
109 |
110 |
An error with a message.
111 |
112 |
113 |
114 |
Declaration
115 |
116 |
Swift
117 |
case message ( String )
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
132 |
133 |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KKCarPlayManager
2 |
3 | [](https://github.com/KKBOX/KKCarPlayManager/actions)
4 | [](http://cocoapods.org/pods/KKCarPlayManager)
5 | [](https://www.apple.com/tw/ios)
6 |
7 | 2019 © KKBOX.
8 |
9 | **KKCarPlayManager** provides a simple, clear and declarative way to implement
10 | the functionalities of [CarPlay](https://www.apple.com/ios/carplay/).
11 |
12 | ## Requirement
13 |
14 | - Xcode
15 | - Swift 4.2 or above
16 | - iOS 8.0 or above
17 |
18 | ## Installation
19 |
20 | You can install the package via Swift Package Manager or CocoaPods.
21 |
22 | ### CocoaPods
23 |
24 | Add `KKCarPlayManager` to your pod file, then run `pod install`.
25 |
26 | ### Swift Package Manager
27 |
28 | Just add `https://github.com/KKBOX/KKCarPlayManager.git` to your `Package.swift`
29 | file, or, you can add the package in Xcode 11 by selecting "File" -> "Swift
30 | Packages" -> "Add Package Dependency".
31 |
32 | ## Example
33 |
34 | The project has an example project. Go to the `Example` folder, run `pod install`,
35 | open `Example.xcworkspace`, build and run the example app.
36 |
37 | ## Getting Started
38 |
39 | Apple does not allow a CarPlay audio app to customize user interface./ You don't
40 | call any method on CarPlay, but let
41 | [MPPlayableContentManager](https://developer.apple.com/documentation/mediaplayer/mpplayablecontentmanager)
42 | to call you, discover your contents, and list them in a structured table user
43 | interface.
44 |
45 | KKCarPlayManager helps you to build your contents into a tree to be discovered.
46 | KKCarPlayManager already implemented the data source and delegate of
47 | MPPlayableContentManager for you, and all you need to do is to give
48 | KKCarPlayManager a root node and its subnodes. For example:
49 |
50 | ``` swift
51 | // Import required modules.
52 |
53 | import KKCarPlayManager
54 | import MediaPlayer
55 | import AVFoundation
56 |
57 | // You should set at least one command of MPRemoteCommandCenter, otherwise
58 | // MPPlayableContentManager won't call it data source and delegate.
59 | MPRemoteCommandCenter.shared().playCommand.addTarget { event in
60 | return .success
61 | }
62 |
63 | // Create a root node.
64 | let rooNode = KKStaticContainerItem(identifier: "root", title: "Root", children: [
65 | KKStaticContainerItem(identifier: "folder1", title: "Folder 1", children: [
66 | PlayItem(identifier: "Song_1_1", title: "Song name", url: "song URL..."),
67 | PlayItem(identifier: "Song_1_2", title: "Song name", url: "song URL..."),
68 | ]),
69 | KKStaticContainerItem(identifier: "folder_2", title: "Folder 2", children: [
70 | PlayItem(identifier: "Song_2_1", title: "Song name", url: "song URL..."),
71 | PlayItem(identifier: "Song_2_2", title: "Song name", url: "song URL...")
72 | ]),
73 | ]
74 | )
75 |
76 | // Create your manager.
77 | manager = KKCarPlayManager(rootNode: rooNode)
78 |
79 | // Sets the data source and delegate of MPPlayableContentManager to the manager.
80 | manager?.activate()
81 | ```
82 |
83 | Actually these nodes are instances of `KKBasicContentItem`. It is a subclass of
84 | `MPContentItem`, and you can subclass `KKBasicContentItem` for your own need.
85 |
86 | ## Items/Nodes
87 |
88 | We added three methods on `KKBasicContentItem`:
89 |
90 | - `KKBasicContentItem.children`: A list of `KKBasicContentItem`.
91 | - `KKBasicContentItem.loadChildren(callback:)`: Ask the item to load its children.
92 | - `KKBasicContentItem.play(callback:)`: Play the item.
93 |
94 | There are two kinds of items/nodes, one is containers while another is playable
95 | items.
96 |
97 | ### Containers
98 |
99 | A container could be list a playlist or an album. It has it children. When you
100 | select a container on the CarPlay screen,
101 | `KKBasicContentItem.loadChildren(callback:)` would be called and the CarPlay
102 | screen goes to the next level and present its children items in a table UI.
103 |
104 | If you want to load children items from a file or from the Internet, subclass a
105 | KKBasicContentItem, set `isPlayable` to false and `isContainer` to true, do your
106 | loading in `KKBasicContentItem.loadChildren(callback:)` and remember to call the
107 | callback closure.
108 |
109 | KKCarPlayManager made a built-in container item type, `KKStaticContainerItem`. You
110 | can just use the class if you have a static list.
111 |
112 | ### Playable Items
113 |
114 | A playable item could be a song track, an audio book and so on. When a playable
115 | item is selected, the `KKBasicContentItem.play(callback:)` method would be
116 | called and your app should start playing. You should create your own subclasses
117 | for playable items in your app, since we are hardly to know how your player
118 | works and creates classes for you.
119 |
120 | If there is any error while playing, call the callback closure and pass the
121 | error, otherwise you can pass `nil`.
122 |
123 | ## A Full CarPlay Experience
124 |
125 | When you want to enable CarPlay in your audio app,
126 |
127 | - You need to have a valid provision profile/entitlement, otherwise your app
128 | won't appear on the CarPlay screen. Please contact Apple.
129 | - You need to enable some commands of [MPRemoteCommandCenter](https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter), otherwise
130 | `MPPlayableContentManager` won't call its data source and delegate.
131 | - Enable audio background mode and set the current category of [AVAudioSession](https://developer.apple.com/documentation/avfoundation/avaudiosession)
132 | to `.playback`, in order to enable background playabck.
133 | - Set up KKCarPlayManager as we mentioned above.
134 | - Once there are changes in your tree, call `MPPlayableContentManager.shared().beginUpdates()` and
135 | `MPPlayableContentManager.shared().endUpdates()`.
136 | - Provide now playing information to [MPNowPlayingInfoCenter](https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter).
137 |
138 | ## One More Thing
139 |
140 | On Xcode 11, you can use Swift UI like syntax to construct the node after
141 | importing `KKCarPlayManagerExtensions`. For example:
142 |
143 | ``` swift
144 | let rooNode = KKStaticContainerItem(identifier: "root", title: "Root") {
145 | KKStaticContainerItem(identifier: "folder1", title: "Folder 1") {
146 | PlayItem(identifier: "Song_1_1", title: "Song name", url: "song URL...")
147 | PlayItem(identifier: "Song_1_2", title: "Song name", url: "song URL...")
148 | }
149 | KKStaticContainerItem(identifier: "folder_2", title: "Folder 2") {
150 | PlayItem(identifier: "Song_2_1", title: "Song name", url: "song URL...")
151 | PlayItem(identifier: "Song_2_2", title: "Song name", url: "song URL...")
152 | }
153 | }
154 | ```
155 |
156 | Enjoy! 🚗
157 |
--------------------------------------------------------------------------------
/docs/Classes/KKStaticContainerItem.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKStaticContainerItem Class Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKStaticContainerItem Class Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | KKStaticContainerItem
58 |
64 | A container item with static children.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
Creates an instance.
84 |
85 |
86 |
87 |
Declaration
88 |
89 |
Swift
90 |
public init ( identifier : String , title : String , children : [ KKBasicContentItem ])
91 |
92 |
93 |
94 |
95 |
Parameters
96 |
97 |
98 |
99 |
100 |
101 | identifier
102 |
103 |
104 |
105 |
106 |
Identifier of the item.
107 |
108 |
109 |
110 |
111 |
112 |
113 | title
114 |
115 |
116 |
117 |
118 |
Title of the item.
119 |
120 |
121 |
122 |
123 |
124 |
125 | children
126 |
127 |
128 |
129 |
130 |
Children of the item.
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Classes/KKStaticContainerItem.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKStaticContainerItem Class Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKStaticContainerItem Class Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | KKStaticContainerItem
58 |
64 | A container item with static children.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
Creates an instance.
84 |
85 |
86 |
87 |
Declaration
88 |
89 |
Swift
90 |
public init ( identifier : String , title : String , children : [ KKBasicContentItem ])
91 |
92 |
93 |
94 |
95 |
Parameters
96 |
97 |
98 |
99 |
100 |
101 | identifier
102 |
103 |
104 |
105 |
106 |
Identifier of the item.
107 |
108 |
109 |
110 |
111 |
112 |
113 | title
114 |
115 |
116 |
117 |
118 |
Title of the item.
119 |
120 |
121 |
122 |
123 |
124 |
125 | children
126 |
127 |
128 |
129 |
130 |
Children of the item.
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/docs/Classes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Classes Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | Classes Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | Classes
58 | The following classes are available globally.
59 |
60 |
61 |
62 |
63 |
64 |
65 |
72 |
73 |
74 |
75 |
76 |
77 |
KKBOX’s own subclass of MPContentItem.
78 |
79 |
See more
80 |
81 |
82 |
Declaration
83 |
84 |
Swift
85 |
open class KKBasicContentItem : MPContentItem
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
104 |
105 |
106 |
107 |
108 |
109 |
A class helps your to build a tree structure of playable items for CarPlay.
110 |
111 |
See more
112 |
113 |
114 |
Declaration
115 |
116 |
Swift
117 |
public class KKCarPlayManager : NSObject
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
136 |
137 |
138 |
139 |
140 |
141 |
A container item with static children.
142 |
143 |
See more
144 |
145 |
146 |
Declaration
147 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
164 |
165 |
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Classes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Classes Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | Classes Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | Classes
58 | The following classes are available globally.
59 |
60 |
61 |
62 |
63 |
64 |
65 |
72 |
73 |
74 |
75 |
76 |
77 |
KKBOX’s own subclass of MPContentItem.
78 |
79 |
See more
80 |
81 |
82 |
Declaration
83 |
84 |
Swift
85 |
open class KKBasicContentItem : MPContentItem
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
104 |
105 |
106 |
107 |
108 |
109 |
A class helps your to build a tree structure of playable items for CarPlay.
110 |
111 |
See more
112 |
113 |
114 |
Declaration
115 |
116 |
Swift
117 |
public class KKCarPlayManager : NSObject
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
136 |
137 |
138 |
139 |
140 |
141 |
A container item with static children.
142 |
143 |
See more
144 |
145 |
146 |
Declaration
147 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
164 |
165 |
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/docs/css/jazzy.css:
--------------------------------------------------------------------------------
1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td {
2 | background: transparent;
3 | border: 0;
4 | margin: 0;
5 | outline: 0;
6 | padding: 0;
7 | vertical-align: baseline; }
8 |
9 | body {
10 | background-color: #f2f2f2;
11 | font-family: Helvetica, freesans, Arial, sans-serif;
12 | font-size: 14px;
13 | -webkit-font-smoothing: subpixel-antialiased;
14 | word-wrap: break-word; }
15 |
16 | h1, h2, h3 {
17 | margin-top: 0.8em;
18 | margin-bottom: 0.3em;
19 | font-weight: 100;
20 | color: black; }
21 |
22 | h1 {
23 | font-size: 2.5em; }
24 |
25 | h2 {
26 | font-size: 2em;
27 | border-bottom: 1px solid #e2e2e2; }
28 |
29 | h4 {
30 | font-size: 13px;
31 | line-height: 1.5;
32 | margin-top: 21px; }
33 |
34 | h5 {
35 | font-size: 1.1em; }
36 |
37 | h6 {
38 | font-size: 1.1em;
39 | color: #777; }
40 |
41 | .section-name {
42 | color: gray;
43 | display: block;
44 | font-family: Helvetica;
45 | font-size: 22px;
46 | font-weight: 100;
47 | margin-bottom: 15px; }
48 |
49 | pre, code {
50 | font: 0.95em Menlo, monospace;
51 | color: #777;
52 | word-wrap: normal; }
53 |
54 | p code, li code {
55 | background-color: #eee;
56 | padding: 2px 4px;
57 | border-radius: 4px; }
58 |
59 | a {
60 | color: #0088cc;
61 | text-decoration: none; }
62 |
63 | ul {
64 | padding-left: 15px; }
65 |
66 | li {
67 | line-height: 1.8em; }
68 |
69 | img {
70 | max-width: 100%; }
71 |
72 | blockquote {
73 | margin-left: 0;
74 | padding: 0 10px;
75 | border-left: 4px solid #ccc; }
76 |
77 | .content-wrapper {
78 | margin: 0 auto;
79 | width: 980px; }
80 |
81 | header {
82 | font-size: 0.85em;
83 | line-height: 26px;
84 | background-color: #414141;
85 | position: fixed;
86 | width: 100%;
87 | z-index: 1; }
88 | header img {
89 | padding-right: 6px;
90 | vertical-align: -4px;
91 | height: 16px; }
92 | header a {
93 | color: #fff; }
94 | header p {
95 | float: left;
96 | color: #999; }
97 | header .header-right {
98 | float: right;
99 | margin-left: 16px; }
100 |
101 | #breadcrumbs {
102 | background-color: #f2f2f2;
103 | height: 27px;
104 | padding-top: 17px;
105 | position: fixed;
106 | width: 100%;
107 | z-index: 1;
108 | margin-top: 26px; }
109 | #breadcrumbs #carat {
110 | height: 10px;
111 | margin: 0 5px; }
112 |
113 | .sidebar {
114 | background-color: #f9f9f9;
115 | border: 1px solid #e2e2e2;
116 | overflow-y: auto;
117 | overflow-x: hidden;
118 | position: fixed;
119 | top: 70px;
120 | bottom: 0;
121 | width: 230px;
122 | word-wrap: normal; }
123 |
124 | .nav-groups {
125 | list-style-type: none;
126 | background: #fff;
127 | padding-left: 0; }
128 |
129 | .nav-group-name {
130 | border-bottom: 1px solid #e2e2e2;
131 | font-size: 1.1em;
132 | font-weight: 100;
133 | padding: 15px 0 15px 20px; }
134 | .nav-group-name > a {
135 | color: #333; }
136 |
137 | .nav-group-tasks {
138 | margin-top: 5px; }
139 |
140 | .nav-group-task {
141 | font-size: 0.9em;
142 | list-style-type: none;
143 | white-space: nowrap; }
144 | .nav-group-task a {
145 | color: #888; }
146 |
147 | .main-content {
148 | background-color: #fff;
149 | border: 1px solid #e2e2e2;
150 | margin-left: 246px;
151 | position: absolute;
152 | overflow: hidden;
153 | padding-bottom: 60px;
154 | top: 70px;
155 | width: 734px; }
156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote {
157 | margin-bottom: 1em; }
158 | .main-content p {
159 | line-height: 1.8em; }
160 | .main-content section .section:first-child {
161 | margin-top: 0;
162 | padding-top: 0; }
163 | .main-content section .task-group-section .task-group:first-of-type {
164 | padding-top: 10px; }
165 | .main-content section .task-group-section .task-group:first-of-type .section-name {
166 | padding-top: 15px; }
167 | .main-content section .heading:before {
168 | content: "";
169 | display: block;
170 | padding-top: 70px;
171 | margin: -70px 0 0; }
172 |
173 | .section {
174 | padding: 0 25px; }
175 |
176 | .highlight {
177 | background-color: #eee;
178 | padding: 10px 12px;
179 | border: 1px solid #e2e2e2;
180 | border-radius: 4px;
181 | overflow-x: auto; }
182 |
183 | .declaration .highlight {
184 | overflow-x: initial;
185 | padding: 0 40px 40px 0;
186 | margin-bottom: -25px;
187 | background-color: transparent;
188 | border: none; }
189 |
190 | .section-name {
191 | margin: 0;
192 | margin-left: 18px; }
193 |
194 | .task-group-section {
195 | padding-left: 6px;
196 | border-top: 1px solid #e2e2e2; }
197 |
198 | .task-group {
199 | padding-top: 0px; }
200 |
201 | .task-name-container a[name]:before {
202 | content: "";
203 | display: block;
204 | padding-top: 70px;
205 | margin: -70px 0 0; }
206 |
207 | .item {
208 | padding-top: 8px;
209 | width: 100%;
210 | list-style-type: none; }
211 | .item a[name]:before {
212 | content: "";
213 | display: block;
214 | padding-top: 70px;
215 | margin: -70px 0 0; }
216 | .item code {
217 | background-color: transparent;
218 | padding: 0; }
219 | .item .token {
220 | padding-left: 3px;
221 | margin-left: 15px;
222 | font-size: 11.9px; }
223 | .item .declaration-note {
224 | font-size: .85em;
225 | color: gray;
226 | font-style: italic; }
227 |
228 | .pointer-container {
229 | border-bottom: 1px solid #e2e2e2;
230 | left: -23px;
231 | padding-bottom: 13px;
232 | position: relative;
233 | width: 110%; }
234 |
235 | .pointer {
236 | background: #f9f9f9;
237 | border-left: 1px solid #e2e2e2;
238 | border-top: 1px solid #e2e2e2;
239 | height: 12px;
240 | left: 21px;
241 | top: -7px;
242 | -webkit-transform: rotate(45deg);
243 | -moz-transform: rotate(45deg);
244 | -o-transform: rotate(45deg);
245 | transform: rotate(45deg);
246 | position: absolute;
247 | width: 12px; }
248 |
249 | .height-container {
250 | display: none;
251 | left: -25px;
252 | padding: 0 25px;
253 | position: relative;
254 | width: 100%;
255 | overflow: hidden; }
256 | .height-container .section {
257 | background: #f9f9f9;
258 | border-bottom: 1px solid #e2e2e2;
259 | left: -25px;
260 | position: relative;
261 | width: 100%;
262 | padding-top: 10px;
263 | padding-bottom: 5px; }
264 |
265 | .aside, .language {
266 | padding: 6px 12px;
267 | margin: 12px 0;
268 | border-left: 5px solid #dddddd;
269 | overflow-y: hidden; }
270 | .aside .aside-title, .language .aside-title {
271 | font-size: 9px;
272 | letter-spacing: 2px;
273 | text-transform: uppercase;
274 | padding-bottom: 0;
275 | margin: 0;
276 | color: #aaa;
277 | -webkit-user-select: none; }
278 | .aside p:last-child, .language p:last-child {
279 | margin-bottom: 0; }
280 |
281 | .language {
282 | border-left: 5px solid #cde9f4; }
283 | .language .aside-title {
284 | color: #4b8afb; }
285 |
286 | .aside-warning {
287 | border-left: 5px solid #ff6666; }
288 | .aside-warning .aside-title {
289 | color: #ff0000; }
290 |
291 | .graybox {
292 | border-collapse: collapse;
293 | width: 100%; }
294 | .graybox p {
295 | margin: 0;
296 | word-break: break-word;
297 | min-width: 50px; }
298 | .graybox td {
299 | border: 1px solid #e2e2e2;
300 | padding: 5px 25px 5px 10px;
301 | vertical-align: middle; }
302 | .graybox tr td:first-of-type {
303 | text-align: right;
304 | padding: 7px;
305 | vertical-align: top;
306 | word-break: normal;
307 | width: 40px; }
308 |
309 | .slightly-smaller {
310 | font-size: 0.9em; }
311 |
312 | #footer {
313 | position: absolute;
314 | bottom: 10px;
315 | margin-left: 25px; }
316 | #footer p {
317 | margin: 0;
318 | color: #aaa;
319 | font-size: 0.8em; }
320 |
321 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar {
322 | display: none; }
323 | html.dash .main-content {
324 | width: 980px;
325 | margin-left: 0;
326 | border: none;
327 | width: 100%;
328 | top: 0;
329 | padding-bottom: 0; }
330 | html.dash .height-container {
331 | display: block; }
332 | html.dash .item .token {
333 | margin-left: 0; }
334 | html.dash .content-wrapper {
335 | width: auto; }
336 | html.dash #footer {
337 | position: static; }
338 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/css/jazzy.css:
--------------------------------------------------------------------------------
1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td {
2 | background: transparent;
3 | border: 0;
4 | margin: 0;
5 | outline: 0;
6 | padding: 0;
7 | vertical-align: baseline; }
8 |
9 | body {
10 | background-color: #f2f2f2;
11 | font-family: Helvetica, freesans, Arial, sans-serif;
12 | font-size: 14px;
13 | -webkit-font-smoothing: subpixel-antialiased;
14 | word-wrap: break-word; }
15 |
16 | h1, h2, h3 {
17 | margin-top: 0.8em;
18 | margin-bottom: 0.3em;
19 | font-weight: 100;
20 | color: black; }
21 |
22 | h1 {
23 | font-size: 2.5em; }
24 |
25 | h2 {
26 | font-size: 2em;
27 | border-bottom: 1px solid #e2e2e2; }
28 |
29 | h4 {
30 | font-size: 13px;
31 | line-height: 1.5;
32 | margin-top: 21px; }
33 |
34 | h5 {
35 | font-size: 1.1em; }
36 |
37 | h6 {
38 | font-size: 1.1em;
39 | color: #777; }
40 |
41 | .section-name {
42 | color: gray;
43 | display: block;
44 | font-family: Helvetica;
45 | font-size: 22px;
46 | font-weight: 100;
47 | margin-bottom: 15px; }
48 |
49 | pre, code {
50 | font: 0.95em Menlo, monospace;
51 | color: #777;
52 | word-wrap: normal; }
53 |
54 | p code, li code {
55 | background-color: #eee;
56 | padding: 2px 4px;
57 | border-radius: 4px; }
58 |
59 | a {
60 | color: #0088cc;
61 | text-decoration: none; }
62 |
63 | ul {
64 | padding-left: 15px; }
65 |
66 | li {
67 | line-height: 1.8em; }
68 |
69 | img {
70 | max-width: 100%; }
71 |
72 | blockquote {
73 | margin-left: 0;
74 | padding: 0 10px;
75 | border-left: 4px solid #ccc; }
76 |
77 | .content-wrapper {
78 | margin: 0 auto;
79 | width: 980px; }
80 |
81 | header {
82 | font-size: 0.85em;
83 | line-height: 26px;
84 | background-color: #414141;
85 | position: fixed;
86 | width: 100%;
87 | z-index: 1; }
88 | header img {
89 | padding-right: 6px;
90 | vertical-align: -4px;
91 | height: 16px; }
92 | header a {
93 | color: #fff; }
94 | header p {
95 | float: left;
96 | color: #999; }
97 | header .header-right {
98 | float: right;
99 | margin-left: 16px; }
100 |
101 | #breadcrumbs {
102 | background-color: #f2f2f2;
103 | height: 27px;
104 | padding-top: 17px;
105 | position: fixed;
106 | width: 100%;
107 | z-index: 1;
108 | margin-top: 26px; }
109 | #breadcrumbs #carat {
110 | height: 10px;
111 | margin: 0 5px; }
112 |
113 | .sidebar {
114 | background-color: #f9f9f9;
115 | border: 1px solid #e2e2e2;
116 | overflow-y: auto;
117 | overflow-x: hidden;
118 | position: fixed;
119 | top: 70px;
120 | bottom: 0;
121 | width: 230px;
122 | word-wrap: normal; }
123 |
124 | .nav-groups {
125 | list-style-type: none;
126 | background: #fff;
127 | padding-left: 0; }
128 |
129 | .nav-group-name {
130 | border-bottom: 1px solid #e2e2e2;
131 | font-size: 1.1em;
132 | font-weight: 100;
133 | padding: 15px 0 15px 20px; }
134 | .nav-group-name > a {
135 | color: #333; }
136 |
137 | .nav-group-tasks {
138 | margin-top: 5px; }
139 |
140 | .nav-group-task {
141 | font-size: 0.9em;
142 | list-style-type: none;
143 | white-space: nowrap; }
144 | .nav-group-task a {
145 | color: #888; }
146 |
147 | .main-content {
148 | background-color: #fff;
149 | border: 1px solid #e2e2e2;
150 | margin-left: 246px;
151 | position: absolute;
152 | overflow: hidden;
153 | padding-bottom: 60px;
154 | top: 70px;
155 | width: 734px; }
156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote {
157 | margin-bottom: 1em; }
158 | .main-content p {
159 | line-height: 1.8em; }
160 | .main-content section .section:first-child {
161 | margin-top: 0;
162 | padding-top: 0; }
163 | .main-content section .task-group-section .task-group:first-of-type {
164 | padding-top: 10px; }
165 | .main-content section .task-group-section .task-group:first-of-type .section-name {
166 | padding-top: 15px; }
167 | .main-content section .heading:before {
168 | content: "";
169 | display: block;
170 | padding-top: 70px;
171 | margin: -70px 0 0; }
172 |
173 | .section {
174 | padding: 0 25px; }
175 |
176 | .highlight {
177 | background-color: #eee;
178 | padding: 10px 12px;
179 | border: 1px solid #e2e2e2;
180 | border-radius: 4px;
181 | overflow-x: auto; }
182 |
183 | .declaration .highlight {
184 | overflow-x: initial;
185 | padding: 0 40px 40px 0;
186 | margin-bottom: -25px;
187 | background-color: transparent;
188 | border: none; }
189 |
190 | .section-name {
191 | margin: 0;
192 | margin-left: 18px; }
193 |
194 | .task-group-section {
195 | padding-left: 6px;
196 | border-top: 1px solid #e2e2e2; }
197 |
198 | .task-group {
199 | padding-top: 0px; }
200 |
201 | .task-name-container a[name]:before {
202 | content: "";
203 | display: block;
204 | padding-top: 70px;
205 | margin: -70px 0 0; }
206 |
207 | .item {
208 | padding-top: 8px;
209 | width: 100%;
210 | list-style-type: none; }
211 | .item a[name]:before {
212 | content: "";
213 | display: block;
214 | padding-top: 70px;
215 | margin: -70px 0 0; }
216 | .item code {
217 | background-color: transparent;
218 | padding: 0; }
219 | .item .token {
220 | padding-left: 3px;
221 | margin-left: 15px;
222 | font-size: 11.9px; }
223 | .item .declaration-note {
224 | font-size: .85em;
225 | color: gray;
226 | font-style: italic; }
227 |
228 | .pointer-container {
229 | border-bottom: 1px solid #e2e2e2;
230 | left: -23px;
231 | padding-bottom: 13px;
232 | position: relative;
233 | width: 110%; }
234 |
235 | .pointer {
236 | background: #f9f9f9;
237 | border-left: 1px solid #e2e2e2;
238 | border-top: 1px solid #e2e2e2;
239 | height: 12px;
240 | left: 21px;
241 | top: -7px;
242 | -webkit-transform: rotate(45deg);
243 | -moz-transform: rotate(45deg);
244 | -o-transform: rotate(45deg);
245 | transform: rotate(45deg);
246 | position: absolute;
247 | width: 12px; }
248 |
249 | .height-container {
250 | display: none;
251 | left: -25px;
252 | padding: 0 25px;
253 | position: relative;
254 | width: 100%;
255 | overflow: hidden; }
256 | .height-container .section {
257 | background: #f9f9f9;
258 | border-bottom: 1px solid #e2e2e2;
259 | left: -25px;
260 | position: relative;
261 | width: 100%;
262 | padding-top: 10px;
263 | padding-bottom: 5px; }
264 |
265 | .aside, .language {
266 | padding: 6px 12px;
267 | margin: 12px 0;
268 | border-left: 5px solid #dddddd;
269 | overflow-y: hidden; }
270 | .aside .aside-title, .language .aside-title {
271 | font-size: 9px;
272 | letter-spacing: 2px;
273 | text-transform: uppercase;
274 | padding-bottom: 0;
275 | margin: 0;
276 | color: #aaa;
277 | -webkit-user-select: none; }
278 | .aside p:last-child, .language p:last-child {
279 | margin-bottom: 0; }
280 |
281 | .language {
282 | border-left: 5px solid #cde9f4; }
283 | .language .aside-title {
284 | color: #4b8afb; }
285 |
286 | .aside-warning {
287 | border-left: 5px solid #ff6666; }
288 | .aside-warning .aside-title {
289 | color: #ff0000; }
290 |
291 | .graybox {
292 | border-collapse: collapse;
293 | width: 100%; }
294 | .graybox p {
295 | margin: 0;
296 | word-break: break-word;
297 | min-width: 50px; }
298 | .graybox td {
299 | border: 1px solid #e2e2e2;
300 | padding: 5px 25px 5px 10px;
301 | vertical-align: middle; }
302 | .graybox tr td:first-of-type {
303 | text-align: right;
304 | padding: 7px;
305 | vertical-align: top;
306 | word-break: normal;
307 | width: 40px; }
308 |
309 | .slightly-smaller {
310 | font-size: 0.9em; }
311 |
312 | #footer {
313 | position: absolute;
314 | bottom: 10px;
315 | margin-left: 25px; }
316 | #footer p {
317 | margin: 0;
318 | color: #aaa;
319 | font-size: 0.8em; }
320 |
321 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar {
322 | display: none; }
323 | html.dash .main-content {
324 | width: 980px;
325 | margin-left: 0;
326 | border: none;
327 | width: 100%;
328 | top: 0;
329 | padding-bottom: 0; }
330 | html.dash .height-container {
331 | display: block; }
332 | html.dash .item .token {
333 | margin-left: 0; }
334 | html.dash .content-wrapper {
335 | width: auto; }
336 | html.dash #footer {
337 | position: static; }
338 |
--------------------------------------------------------------------------------
/docs/Classes/KKCarPlayManager.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKCarPlayManager Class Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKCarPlayManager Class Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | KKCarPlayManager
58 |
59 |
60 |
public class KKCarPlayManager : NSObject
61 |
62 |
63 |
64 | A class helps your to build a tree structure of playable items for CarPlay.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
Set the data source and delegate of MPPlayableContentManager to
84 | the current instance of KKCarPlayManager.
85 |
86 |
87 |
88 |
Declaration
89 |
90 |
Swift
91 |
public func activate ()
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
106 |
107 |
108 |
109 |
110 |
111 |
Set the data source and delegate of MPPlayableContentManager to nil.
112 |
113 |
114 |
115 |
Declaration
116 |
117 |
Swift
118 |
public func deactivate ()
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
133 |
134 |
135 |
136 |
137 |
138 |
Creates a new instance.
139 |
140 |
141 |
142 |
Declaration
143 |
148 |
149 |
150 |
Parameters
151 |
152 |
153 |
154 |
155 |
156 | rootNode
157 |
158 |
159 |
160 |
161 |
The root node.
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
179 |
180 |
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Classes/KKCarPlayManager.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKCarPlayManager Class Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKCarPlayManager Class Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | KKCarPlayManager
58 |
59 |
60 |
public class KKCarPlayManager : NSObject
61 |
62 |
63 |
64 | A class helps your to build a tree structure of playable items for CarPlay.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
Set the data source and delegate of MPPlayableContentManager to
84 | the current instance of KKCarPlayManager.
85 |
86 |
87 |
88 |
Declaration
89 |
90 |
Swift
91 |
public func activate ()
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
106 |
107 |
108 |
109 |
110 |
111 |
Set the data source and delegate of MPPlayableContentManager to nil.
112 |
113 |
114 |
115 |
Declaration
116 |
117 |
Swift
118 |
public func deactivate ()
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
133 |
134 |
135 |
136 |
137 |
138 |
Creates a new instance.
139 |
140 |
141 |
142 |
Declaration
143 |
148 |
149 |
150 |
Parameters
151 |
152 |
153 |
154 |
155 |
156 | rootNode
157 |
158 |
159 |
160 |
161 |
The root node.
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
179 |
180 |
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/docs/Classes/KKBasicContentItem.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKBasicContentItem Class Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKBasicContentItem Class Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | KKBasicContentItem
58 |
59 |
60 |
open class KKBasicContentItem : MPContentItem
61 |
62 |
63 |
64 | KKBOX’s own subclass of MPContentItem.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
Childten items of the item. We use this property to build a tree and
84 | feed item on each index path to MPPlayableContentManager.
85 |
86 |
87 |
88 |
Declaration
89 |
90 |
Swift
91 |
open var children : [ KKBasicContentItem ]?
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
106 |
107 |
108 |
109 |
110 |
111 |
To load the children of the node.
112 |
113 |
114 |
115 |
Declaration
116 |
117 |
Swift
118 |
open func loadChildren ( callback : @escaping ( Error ?) -> Void ) throws
119 |
120 |
121 |
122 |
123 |
Parameters
124 |
125 |
126 |
127 |
128 |
129 | callback
130 |
131 |
132 |
133 |
134 |
the callback function. It contains an error object if it
135 | encounters any error while loading.
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
153 |
154 |
155 |
156 |
157 |
158 |
To play the media mapping to the item.
159 |
160 |
161 |
162 |
Declaration
163 |
164 |
Swift
165 |
open func play ( callback : @escaping ( Error ?) -> Void ) throws -> Bool
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
184 |
185 |
186 |
187 |
188 |
189 |
Apply an image to the current item.
190 |
191 |
192 |
193 |
Declaration
194 |
195 |
Swift
196 |
public func apply ( image : UIImage ?) -> KKBasicContentItem
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
211 |
212 |
213 |
214 |
215 |
216 |
--------------------------------------------------------------------------------
/docs/docsets/KKCarPlayManager.docset/Contents/Resources/Documents/Classes/KKBasicContentItem.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | KKBasicContentItem Class Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 | KKCarPlayManager Reference
23 |
24 | KKBasicContentItem Class Reference
25 |
26 |
27 |
28 |
54 |
55 |
56 |
57 | KKBasicContentItem
58 |
59 |
60 |
open class KKBasicContentItem : MPContentItem
61 |
62 |
63 |
64 | KKBOX’s own subclass of MPContentItem.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
Childten items of the item. We use this property to build a tree and
84 | feed item on each index path to MPPlayableContentManager.
85 |
86 |
87 |
88 |
Declaration
89 |
90 |
Swift
91 |
open var children : [ KKBasicContentItem ]?
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
106 |
107 |
108 |
109 |
110 |
111 |
To load the children of the node.
112 |
113 |
114 |
115 |
Declaration
116 |
117 |
Swift
118 |
open func loadChildren ( callback : @escaping ( Error ?) -> Void ) throws
119 |
120 |
121 |
122 |
123 |
Parameters
124 |
125 |
126 |
127 |
128 |
129 | callback
130 |
131 |
132 |
133 |
134 |
the callback function. It contains an error object if it
135 | encounters any error while loading.
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
153 |
154 |
155 |
156 |
157 |
158 |
To play the media mapping to the item.
159 |
160 |
161 |
162 |
Declaration
163 |
164 |
Swift
165 |
open func play ( callback : @escaping ( Error ?) -> Void ) throws -> Bool
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
184 |
185 |
186 |
187 |
188 |
189 |
Apply an image to the current item.
190 |
191 |
192 |
193 |
Declaration
194 |
195 |
Swift
196 |
public func apply ( image : UIImage ?) -> KKBasicContentItem
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
211 |
212 |
213 |
214 |
215 |
216 |
--------------------------------------------------------------------------------