Browse Source

init

master
Marco Schmickler 11 years ago
parent
commit
f17b9585b7
  1. 4
      .idea/encodings.xml
  2. 8
      .idea/kplayer.iml
  3. 4
      .idea/misc.xml
  4. 8
      .idea/modules.xml
  5. 5
      .idea/scopes/scope_settings.xml
  6. 6
      .idea/vcs.xml
  7. 4
      .idea/xcode.xml
  8. 7
      Podfile
  9. 115
      kplayer.xcodeproj/project.pbxproj
  10. 1
      kplayer/AppDelegate.swift
  11. 12
      kplayer/Base.lproj/Main.storyboard
  12. 284
      kplayer/DetailViewController.swift
  13. 53
      kplayer/ItemCell.swift
  14. BIN
      kplayer/Kirschkeks-256x256.png
  15. 45
      kplayer/LayoutTools.swift
  16. 147
      kplayer/MasterViewController.swift
  17. 9
      kplayer/VideoPlayerController.swift
  18. 38
      kplayer/core/MediaItem.swift
  19. 72
      kplayer/core/NetworkManager.swift

4
.idea/encodings.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>

8
.idea/kplayer.iml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="CIDR_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

4
.idea/misc.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" />
</project>

8
.idea/modules.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/kplayer.iml" filepath="$PROJECT_DIR$/.idea/kplayer.iml" />
</modules>
</component>
</project>

5
.idea/scopes/scope_settings.xml

@ -0,0 +1,5 @@
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>

6
.idea/vcs.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

4
.idea/xcode.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="XcodeMetaData" PROJECT_FILE="$PROJECT_DIR$/kplayer.xcworkspace" />
</project>

7
Podfile

@ -0,0 +1,7 @@
platform :ios, '8.3'
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
# pod 'Player'
pod 'Alamofire', '~> 1.2'

115
kplayer.xcodeproj/project.pbxproj

@ -7,6 +7,14 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1C736261CBA1D13D16DCBAFB /* VideoPlayerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7366EF59D75216EBC0D3F0 /* VideoPlayerController.swift */; };
1C73635138BBD2BB480A308F /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C736777456388CA571DA17B /* MediaPlayer.framework */; };
1C7363D9DC8F9D1F866DE935 /* Kirschkeks-256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C7368DC7EF11A553145E169 /* Kirschkeks-256x256.png */; };
1C73641627BE29D9FA819F3C /* LayoutTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73649CEA7BDD2AC1496F76 /* LayoutTools.swift */; };
1C736503B656C999E5E12081 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7365B06FA66294E99AC2D3 /* NetworkManager.swift */; };
1C736C90DB50C4FDED266C3D /* ItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7362C647AEBF03F5FD9FEB /* ItemCell.swift */; };
1C736FB92B19FE17E4357C85 /* MediaItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73688DAB88F9360FB62A49 /* MediaItem.swift */; };
A5D637AE4588AAB5DC1CBC6B /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 127AC1F28342F9AAE3CEC5C2 /* Pods.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
C98AF5D51B124D6A00D196CC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98AF5D41B124D6A00D196CC /* AppDelegate.swift */; }; C98AF5D51B124D6A00D196CC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98AF5D41B124D6A00D196CC /* AppDelegate.swift */; };
C98AF5D81B124D6A00D196CC /* kplayer.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C98AF5D61B124D6A00D196CC /* kplayer.xcdatamodeld */; }; C98AF5D81B124D6A00D196CC /* kplayer.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C98AF5D61B124D6A00D196CC /* kplayer.xcdatamodeld */; };
C98AF5DA1B124D6A00D196CC /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98AF5D91B124D6A00D196CC /* MasterViewController.swift */; }; C98AF5DA1B124D6A00D196CC /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98AF5D91B124D6A00D196CC /* MasterViewController.swift */; };
@ -28,6 +36,16 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
127AC1F28342F9AAE3CEC5C2 /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1C7362C647AEBF03F5FD9FEB /* ItemCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemCell.swift; sourceTree = "<group>"; };
1C73649CEA7BDD2AC1496F76 /* LayoutTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutTools.swift; sourceTree = "<group>"; };
1C7365B06FA66294E99AC2D3 /* NetworkManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = "<group>"; };
1C7366EF59D75216EBC0D3F0 /* VideoPlayerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoPlayerController.swift; sourceTree = "<group>"; };
1C736777456388CA571DA17B /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
1C73688DAB88F9360FB62A49 /* MediaItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaItem.swift; sourceTree = "<group>"; };
1C7368DC7EF11A553145E169 /* Kirschkeks-256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Kirschkeks-256x256.png"; sourceTree = "<group>"; };
5C6CBA548F885BF342F594EA /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
A170BFB886D61D57F7009BFC /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
C98AF5CF1B124D6A00D196CC /* kplayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = kplayer.app; sourceTree = BUILT_PRODUCTS_DIR; }; C98AF5CF1B124D6A00D196CC /* kplayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = kplayer.app; sourceTree = BUILT_PRODUCTS_DIR; };
C98AF5D31B124D6A00D196CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; C98AF5D31B124D6A00D196CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C98AF5D41B124D6A00D196CC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; C98AF5D41B124D6A00D196CC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -47,6 +65,8 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A5D637AE4588AAB5DC1CBC6B /* Pods.framework in Frameworks */,
1C73635138BBD2BB480A308F /* MediaPlayer.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -60,12 +80,41 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
1C736DC8C3AFB991541A2079 /* core */ = {
isa = PBXGroup;
children = (
1C7365B06FA66294E99AC2D3 /* NetworkManager.swift */,
1C73688DAB88F9360FB62A49 /* MediaItem.swift */,
);
path = core;
sourceTree = "<group>";
};
8CB608B13A2BDFA9D708982B /* Frameworks */ = {
isa = PBXGroup;
children = (
127AC1F28342F9AAE3CEC5C2 /* Pods.framework */,
1C736777456388CA571DA17B /* MediaPlayer.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
8EB26707CC8BD3E10F328A9E /* Pods */ = {
isa = PBXGroup;
children = (
5C6CBA548F885BF342F594EA /* Pods.debug.xcconfig */,
A170BFB886D61D57F7009BFC /* Pods.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
C98AF5C61B124D6A00D196CC = { C98AF5C61B124D6A00D196CC = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C98AF5D11B124D6A00D196CC /* kplayer */, C98AF5D11B124D6A00D196CC /* kplayer */,
C98AF5EC1B124D6A00D196CC /* kplayerTests */, C98AF5EC1B124D6A00D196CC /* kplayerTests */,
C98AF5D01B124D6A00D196CC /* Products */, C98AF5D01B124D6A00D196CC /* Products */,
8EB26707CC8BD3E10F328A9E /* Pods */,
8CB608B13A2BDFA9D708982B /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -89,6 +138,11 @@
C98AF5E21B124D6A00D196CC /* LaunchScreen.xib */, C98AF5E21B124D6A00D196CC /* LaunchScreen.xib */,
C98AF5D61B124D6A00D196CC /* kplayer.xcdatamodeld */, C98AF5D61B124D6A00D196CC /* kplayer.xcdatamodeld */,
C98AF5D21B124D6A00D196CC /* Supporting Files */, C98AF5D21B124D6A00D196CC /* Supporting Files */,
1C736DC8C3AFB991541A2079 /* core */,
1C7362C647AEBF03F5FD9FEB /* ItemCell.swift */,
1C73649CEA7BDD2AC1496F76 /* LayoutTools.swift */,
1C7368DC7EF11A553145E169 /* Kirschkeks-256x256.png */,
1C7366EF59D75216EBC0D3F0 /* VideoPlayerController.swift */,
); );
path = kplayer; path = kplayer;
sourceTree = "<group>"; sourceTree = "<group>";
@ -125,9 +179,12 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = C98AF5F31B124D6A00D196CC /* Build configuration list for PBXNativeTarget "kplayer" */; buildConfigurationList = C98AF5F31B124D6A00D196CC /* Build configuration list for PBXNativeTarget "kplayer" */;
buildPhases = ( buildPhases = (
FA5E42A873B9445C28CCC025 /* Check Pods Manifest.lock */,
C98AF5CB1B124D6A00D196CC /* Sources */, C98AF5CB1B124D6A00D196CC /* Sources */,
C98AF5CC1B124D6A00D196CC /* Frameworks */, C98AF5CC1B124D6A00D196CC /* Frameworks */,
C98AF5CD1B124D6A00D196CC /* Resources */, C98AF5CD1B124D6A00D196CC /* Resources */,
81E453B289EA9615E1980098 /* Embed Pods Frameworks */,
F554AE493C60519505E761A6 /* Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -201,6 +258,7 @@
C98AF5DF1B124D6A00D196CC /* Main.storyboard in Resources */, C98AF5DF1B124D6A00D196CC /* Main.storyboard in Resources */,
C98AF5E41B124D6A00D196CC /* LaunchScreen.xib in Resources */, C98AF5E41B124D6A00D196CC /* LaunchScreen.xib in Resources */,
C98AF5E11B124D6A00D196CC /* Images.xcassets in Resources */, C98AF5E11B124D6A00D196CC /* Images.xcassets in Resources */,
1C7363D9DC8F9D1F866DE935 /* Kirschkeks-256x256.png in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -213,6 +271,54 @@
}; };
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
81E453B289EA9615E1980098 /* Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
F554AE493C60519505E761A6 /* Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
showEnvVarsInLog = 0;
};
FA5E42A873B9445C28CCC025 /* Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
C98AF5CB1B124D6A00D196CC /* Sources */ = { C98AF5CB1B124D6A00D196CC /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
@ -222,6 +328,11 @@
C98AF5D51B124D6A00D196CC /* AppDelegate.swift in Sources */, C98AF5D51B124D6A00D196CC /* AppDelegate.swift in Sources */,
C98AF5DA1B124D6A00D196CC /* MasterViewController.swift in Sources */, C98AF5DA1B124D6A00D196CC /* MasterViewController.swift in Sources */,
C98AF5DC1B124D6A00D196CC /* DetailViewController.swift in Sources */, C98AF5DC1B124D6A00D196CC /* DetailViewController.swift in Sources */,
1C736503B656C999E5E12081 /* NetworkManager.swift in Sources */,
1C736FB92B19FE17E4357C85 /* MediaItem.swift in Sources */,
1C736C90DB50C4FDED266C3D /* ItemCell.swift in Sources */,
1C73641627BE29D9FA819F3C /* LayoutTools.swift in Sources */,
1C736261CBA1D13D16DCBAFB /* VideoPlayerController.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -348,6 +459,7 @@
}; };
C98AF5F41B124D6A00D196CC /* Debug */ = { C98AF5F41B124D6A00D196CC /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 5C6CBA548F885BF342F594EA /* Pods.debug.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = kplayer/Info.plist; INFOPLIST_FILE = kplayer/Info.plist;
@ -358,6 +470,7 @@
}; };
C98AF5F51B124D6A00D196CC /* Release */ = { C98AF5F51B124D6A00D196CC /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = A170BFB886D61D57F7009BFC /* Pods.release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = kplayer/Info.plist; INFOPLIST_FILE = kplayer/Info.plist;
@ -419,6 +532,7 @@
C98AF5F51B124D6A00D196CC /* Release */, C98AF5F51B124D6A00D196CC /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
}; };
C98AF5F61B124D6A00D196CC /* Build configuration list for PBXNativeTarget "kplayerTests" */ = { C98AF5F61B124D6A00D196CC /* Build configuration list for PBXNativeTarget "kplayerTests" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
@ -427,6 +541,7 @@
C98AF5F81B124D6A00D196CC /* Release */, C98AF5F81B124D6A00D196CC /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */

1
kplayer/AppDelegate.swift

@ -24,7 +24,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele
let masterNavigationController = splitViewController.viewControllers[0] as! UINavigationController let masterNavigationController = splitViewController.viewControllers[0] as! UINavigationController
let controller = masterNavigationController.topViewController as! MasterViewController let controller = masterNavigationController.topViewController as! MasterViewController
controller.managedObjectContext = self.managedObjectContext
return true return true
} }

12
kplayer/Base.lproj/Main.storyboard

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="H1p-Uh-vWS">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="H1p-Uh-vWS">
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
</dependencies> </dependencies>
<scenes> <scenes>
<!--Master--> <!--Master-->
@ -22,7 +22,7 @@
<!--Detail--> <!--Detail-->
<scene sceneID="yUG-lL-AsK"> <scene sceneID="yUG-lL-AsK">
<objects> <objects>
<viewController title="Detail" id="JEX-9P-axG" customClass="DetailViewController" customModuleProvider="target" sceneMemberID="viewController">
<viewController title="Detail" id="JEX-9P-axG" customClass="DetailViewController" customModule="kplayer" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides> <layoutGuides>
<viewControllerLayoutGuide type="top" id="SYR-Wa-9uf"/> <viewControllerLayoutGuide type="top" id="SYR-Wa-9uf"/>
<viewControllerLayoutGuide type="bottom" id="GAO-Cl-Wes"/> <viewControllerLayoutGuide type="bottom" id="GAO-Cl-Wes"/>
@ -35,7 +35,7 @@
<rect key="frame" x="20" y="292" width="560" height="17"/> <rect key="frame" x="20" y="292" width="560" height="17"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" type="system" size="system"/> <fontDescription key="fontDescription" type="system" size="system"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
</subviews> </subviews>
@ -73,7 +73,7 @@
<!--Master--> <!--Master-->
<scene sceneID="smW-Zh-WAh"> <scene sceneID="smW-Zh-WAh">
<objects> <objects>
<tableViewController title="Master" clearsSelectionOnViewWillAppear="NO" id="7bK-jq-Zjz" customClass="MasterViewController" customModuleProvider="target" sceneMemberID="viewController">
<tableViewController title="Master" clearsSelectionOnViewWillAppear="NO" id="7bK-jq-Zjz" customClass="MasterViewController" customModule="kplayer" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="r7i-6Z-zg0"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="r7i-6Z-zg0">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/> <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -90,7 +90,7 @@
<rect key="frame" x="15" y="0.0" width="290" height="43"/> <rect key="frame" x="15" y="0.0" width="290" height="43"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="20"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="20"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</label> </label>
</subviews> </subviews>

284
kplayer/DetailViewController.swift

@ -7,32 +7,164 @@
// //
import UIKit import UIKit
import MediaPlayer
class DetailViewController: UIViewController {
class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
@IBOutlet weak var detailDescriptionLabel: UILabel! @IBOutlet weak var detailDescriptionLabel: UILabel!
var moviePlayer: MPMoviePlayerController?
var detailItem: AnyObject? {
var collectionView: UICollectionView!
var detailItem: MediaItem? {
didSet { didSet {
println(detailItem!.children)
if collectionView != nil {
collectionView.reloadData()
}
// Update the view. // Update the view.
self.configureView()
// self.configureView()
} }
} }
var currentItem: MediaItem?
func configureView() { func configureView() {
// Update the user interface for the detail item. // Update the user interface for the detail item.
if let detail: AnyObject = self.detailItem {
println(detailItem)
if let detail: MediaItem = self.detailItem {
println(detail)
println(detail.children)
if let label = self.detailDescriptionLabel { if let label = self.detailDescriptionLabel {
label.text = detail.valueForKey("timeStamp")!.description
label.text = detail.name
}
if count(detail.children) > 0 {
let i = detail.children[0]
var url = NetworkManager.sharedInstance.playerURL(i)
println(url)
// if moviePlayer == nil {
play(url)
// }
} }
} }
}
func play(url: String) {
self.moviePlayer = MPMoviePlayerController()
if let player = self.moviePlayer {
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("exitedFullscreen"), name: MPMoviePlayerDidExitFullscreenNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("enteredFullscreen"), name: MPMoviePlayerDidEnterFullscreenNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("showThumbnail:"), name: MPMoviePlayerThumbnailImageRequestDidFinishNotification, object: nil);
player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
player.view.sizeToFit()
player.scalingMode = MPMovieScalingMode.AspectFit
player.controlStyle = MPMovieControlStyle.Embedded
player.movieSourceType = MPMovieSourceType.Streaming
player.repeatMode = MPMovieRepeatMode.One
player.contentURL = NSURL(string: url)
player.play()
var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("update"), userInfo: nil, repeats: false)
self.view.addSubview(player.view)
}
}
func showThumbnail(note: NSNotification) {
let userInfo = note.userInfo! as NSDictionary
let thumbnail = userInfo.objectForKey(MPMoviePlayerThumbnailImageKey) as! UIImage
let time = userInfo.objectForKey(MPMoviePlayerThumbnailTimeKey) as! NSTimeInterval
let newItem = MediaItem(name: currentItem!.name, path: currentItem!.path, root: currentItem!.root, type: ItemType.SNAPSHOT)
newItem.image = thumbnail
newItem.time = time
newItem.parent = currentItem!
currentItem!.children.append(newItem)
println (newItem.time)
}
func update() {
if let player = self.moviePlayer {
if let t = currentItem!.time {
player.currentPlaybackTime = t
}
else {
println(player.duration)
player.currentPlaybackTime = player.duration / 2
}
if currentItem!.type == ItemType.SNAPSHOT {
currentItem = currentItem!.parent
}
player.fullscreen = true
}
}
func enteredFullscreen() {
let mp = UIApplication.sharedApplication().keyWindow;
if let moviePlayerContainer = recursiveSearchForViewWithName(mp!, classname: "MPVideoContainerView") {
if (moviePlayerContainer.gestureRecognizers != nil) {
return;
}
installGestures(moviePlayerContainer)
}
}
func exitedFullscreen() {
moviePlayer!.view.removeFromSuperview();
moviePlayer = nil;
NSNotificationCenter.defaultCenter().removeObserver(self);
collectionView.reloadData()
collectionView.collectionViewLayout.invalidateLayout()
}
override func loadView() {
super.loadView()
} }
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
layout.itemSize = CGSize(width: 14 * 16 , height: 14 * 10)
layout.headerReferenceSize = CGSize(width: 50, height: 50)
collectionView = UICollectionView(frame: view.frame, collectionViewLayout: layout)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.registerClass(ItemCell.self, forCellWithReuseIdentifier: "Cell")
collectionView.backgroundColor = UIColor.greenColor()
collectionView.registerClass(ItemCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderView");
view.addSubview(collectionView)
// view.autoresizesSubviews = true
// collectionView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
// Do any additional setup after loading the view, typically from a nib. // Do any additional setup after loading the view, typically from a nib.
self.configureView()
collectionView.reloadData()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// self.configureView()
} }
override func didReceiveMemoryWarning() { override func didReceiveMemoryWarning() {
@ -40,6 +172,146 @@ class DetailViewController: UIViewController {
// Dispose of any resources that can be recreated. // Dispose of any resources that can be recreated.
} }
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
if let detail: MediaItem = self.detailItem {
let cnt = count(detail.children)
println(cnt)
return cnt
}
return 0
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let detail: MediaItem = self.detailItem {
return count(detail.children[section].children) + 1
}
return 0
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! ItemCell
if let detail: MediaItem = self.detailItem {
let items = detail.children[indexPath.section]
if indexPath.item >= count(items.children) {
cell.setItem(items)
} else {
let item = items.children[indexPath.item]
cell.setItem(item)
}
}
cell.backgroundColor = UIColor.blueColor()
return cell
}
func collectionView(collectionView: UICollectionView,
viewForSupplementaryElementOfKind kind: String,
atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView =
collectionView.dequeueReusableSupplementaryViewOfKind(kind,
withReuseIdentifier: "HeaderView",
forIndexPath: indexPath)
as! ItemCell
let items = detailItem!.children[indexPath.section]
println("sec \(indexPath.section) " + items.name)
headerView.label.text = items.name
headerView.backgroundColor = UIColor.yellowColor()
return headerView
default:
assert(false, "Unexpected element kind")
}
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if let detail: MediaItem = self.detailItem {
var items = detail.children[indexPath.section]
if indexPath.item >= count(items.children) {
println(items.name)
} else {
items = items.children[indexPath.item]
println(items.name)
}
currentItem = items
var url = NetworkManager.sharedInstance.playerURL(items)
println(url)
play(url)
}
}
func installGestures(moviePlayer: UIView) {
let twoFingersTwoTaps = UITapGestureRecognizer(target: self, action: "twoFingersTwoTaps")
twoFingersTwoTaps.numberOfTapsRequired = 2
twoFingersTwoTaps.numberOfTouchesRequired = 2
moviePlayer.addGestureRecognizer(twoFingersTwoTaps)
let sR = UISwipeGestureRecognizer(target: self, action: "swipeRight")
sR.direction = UISwipeGestureRecognizerDirection.Right
sR.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sR)
let sL = UISwipeGestureRecognizer(target: self, action: "swipeLeft")
sL.direction = UISwipeGestureRecognizerDirection.Left
sL.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sL)
let sR2 = UISwipeGestureRecognizer(target: self, action: "swipeDown")
sR2.direction = UISwipeGestureRecognizerDirection.Down
sR2.numberOfTouchesRequired = 1
moviePlayer.addGestureRecognizer(sR2)
}
func swipeRight() {
println("r")
if let player = self.moviePlayer {
player.currentPlaybackTime = player.currentPlaybackTime + 30.0
}
}
func swipeDown() {
println("r")
if let player = self.moviePlayer {
player.currentPlaybackTime = player.currentPlaybackTime + 10.0
}
}
func swipeLeft() {
println("l")
if let player = self.moviePlayer {
player.currentPlaybackTime = player.currentPlaybackTime - 30.0
}
}
func twoFingersTwoTaps() {
println("tap")
moviePlayer!.requestThumbnailImagesAtTimes([moviePlayer!.currentPlaybackTime],
timeOption:MPMovieTimeOption.NearestKeyFrame);
}
func recursiveSearchForViewWithName(view: UIView, classname: String) -> UIView? {
for v in view.subviews {
var result = recursiveSearchForViewWithName(v as! UIView, classname: classname)
let cn = toString(v.dynamicType)
if cn == classname {
return v as! UIView
}
if result != nil {
return result
}
}
return nil
}
} }

53
kplayer/ItemCell.swift

@ -0,0 +1,53 @@
//
// Created by Marco Schmickler on 25.05.15.
// Copyright (c) 2015 Marco Schmickler. All rights reserved.
//
import Foundation
import UIKit
class ItemCell: UICollectionViewCell {
var item: MediaItem?
var label: UILabel!
var image: UIImageView!
required init(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
label = UILabel(frame: frame)
image = UIImageView()
image.layer.borderWidth = 2.0;
autolayout(["label": label, "imag": image],
constraints:
"H:|-5-[label]-5-|",
"H:|-5-[imag]-5-|",
"V:|-5-[label(<=50)]-5-[imag]-5-|" )
}
func setItem(item: MediaItem) {
self.item = item
label.text = item.name
if let i = item.image {
println (i)
image.image = i
image.sizeToFit()
}
else {
image.image = UIImage(named: "Kirschkeks-256x256.png")
}
}
}

BIN
kplayer/Kirschkeks-256x256.png

After

Width: 256  |  Height: 256  |  Size: 127 KiB

45
kplayer/LayoutTools.swift

@ -0,0 +1,45 @@
//
// Created by Marco Schmickler on 25.05.15.
// Copyright (c) 2015 Marco Schmickler. All rights reserved.
//
import Foundation
import UIKit
public extension UIView {
func autolayout(views: [String:UIView!], constraints: Any...) {
autolay(views, constraints:constraints)
}
func autolay(views: [String:UIView!], constraints: [Any]) {
var index = 0;
for value in views.values {
let vv: UIView = value
addSubview(vv)
vv.setTranslatesAutoresizingMaskIntoConstraints(false)
}
while index < constraints.count {
let c = constraints[index]
if c is String {
if index + 1 < constraints.count && !(constraints[index + 1] is String) {
index++
let constr: NSArray = NSLayoutConstraint.constraintsWithVisualFormat(c as! String,
options: constraints[index] as! NSLayoutFormatOptions,
metrics: nil,
views: views)
addConstraints(constr as [AnyObject])
} else {
let constr: NSArray = NSLayoutConstraint.constraintsWithVisualFormat(c as! String,
options: NSLayoutFormatOptions(0), metrics: nil, views: views)
addConstraints(constr as [AnyObject])
}
}
index++
}
}
}

147
kplayer/MasterViewController.swift

@ -9,11 +9,11 @@
import UIKit import UIKit
import CoreData import CoreData
class MasterViewController: UITableViewController, NSFetchedResultsControllerDelegate {
class MasterViewController: UITableViewController {
var detailViewController: DetailViewController? = nil var detailViewController: DetailViewController? = nil
var managedObjectContext: NSManagedObjectContext? = nil
var items = [MediaItem]()
override func awakeFromNib() { override func awakeFromNib() {
super.awakeFromNib() super.awakeFromNib()
@ -25,6 +25,28 @@ class MasterViewController: UITableViewController, NSFetchedResultsControllerDel
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
NetworkManager.sharedInstance.loadDirs("/srv/samba/ren/knk_archiv4") { (g) in
var d = Dictionary<String, MediaItem>()
for f in g {
var p = d[f.path]
if p == nil {
p = MediaItem(name: "", path: f.path, root: f.root, type: ItemType.FOLDER)
d[f.path] = p!
println(p)
}
p!.children.append(f)
f.parent = p!
}
self.items = Array(d.values)
self.tableView.reloadData()
}
// Do any additional setup after loading the view, typically from a nib. // Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem() self.navigationItem.leftBarButtonItem = self.editButtonItem()
@ -42,22 +64,6 @@ class MasterViewController: UITableViewController, NSFetchedResultsControllerDel
} }
func insertNewObject(sender: AnyObject) { func insertNewObject(sender: AnyObject) {
let context = self.fetchedResultsController.managedObjectContext
let entity = self.fetchedResultsController.fetchRequest.entity!
let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName(entity.name!, inManagedObjectContext: context) as! NSManagedObject
// If appropriate, configure the new managed object.
// Normally you should use accessor methods, but using KVC here avoids the need to add a custom class to the template.
newManagedObject.setValue(NSDate(), forKey: "timeStamp")
// Save the context.
var error: NSError? = nil
if !context.save(&error) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
//println("Unresolved error \(error), \(error.userInfo)")
abort()
}
} }
// MARK: - Segues // MARK: - Segues
@ -65,7 +71,7 @@ class MasterViewController: UITableViewController, NSFetchedResultsControllerDel
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" { if segue.identifier == "showDetail" {
if let indexPath = self.tableView.indexPathForSelectedRow() { if let indexPath = self.tableView.indexPathForSelectedRow() {
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject
let object = items[indexPath.row]
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object controller.detailItem = object
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem() controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
@ -77,12 +83,11 @@ class MasterViewController: UITableViewController, NSFetchedResultsControllerDel
// MARK: - Table View // MARK: - Table View
override func numberOfSectionsInTableView(tableView: UITableView) -> Int { override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.fetchedResultsController.sections?.count ?? 0
return 1
} }
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = self.fetchedResultsController.sections![section] as! NSFetchedResultsSectionInfo
return sectionInfo.numberOfObjects
return count(items)
} }
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
@ -93,111 +98,19 @@ class MasterViewController: UITableViewController, NSFetchedResultsControllerDel
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable. // Return false if you do not want the specified item to be editable.
return true
return false
} }
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete { if editingStyle == .Delete {
let context = self.fetchedResultsController.managedObjectContext
context.deleteObject(self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject)
var error: NSError? = nil
if !context.save(&error) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
//println("Unresolved error \(error), \(error.userInfo)")
abort()
}
} }
} }
func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) { func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject
cell.textLabel!.text = object.valueForKey("timeStamp")!.description
}
// MARK: - Fetched results controller
var fetchedResultsController: NSFetchedResultsController {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest()
// Edit the entity name as appropriate.
let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: self.managedObjectContext!)
fetchRequest.entity = entity
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20
// Edit the sort key as appropriate.
let sortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
let sortDescriptors = [sortDescriptor]
fetchRequest.sortDescriptors = [sortDescriptor]
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master")
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController
var error: NSError? = nil
if !_fetchedResultsController!.performFetch(&error) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
//println("Unresolved error \(error), \(error.userInfo)")
abort()
}
return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController? = nil
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case .Insert:
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
case .Delete:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
default:
return
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
case .Delete:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Update:
self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, atIndexPath: indexPath!)
case .Move:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
default:
return
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView.endUpdates()
let object = items[indexPath.row]
cell.textLabel!.text = object.path
} }
/*
// Implementing the above methods to update the table view in response to individual changes may have performance implications if a large number of changes are made simultaneously. If this proves to be an issue, you can instead just implement controllerDidChangeContent: which notifies the delegate that all section and object changes have been processed.
func controllerDidChangeContent(controller: NSFetchedResultsController) {
// In the simplest, most efficient, case, reload the table view.
self.tableView.reloadData()
}
*/
} }

9
kplayer/VideoPlayerController.swift

@ -0,0 +1,9 @@
//
// Created by Marco Schmickler on 26.05.15.
// Copyright (c) 2015 Marco Schmickler. All rights reserved.
//
import Foundation
class VideoPlayerController {
}

38
kplayer/core/MediaItem.swift

@ -0,0 +1,38 @@
//
// Created by Marco Schmickler on 25.05.15.
// Copyright (c) 2015 Marco Schmickler. All rights reserved.
//
import Foundation
import UIKit
enum ItemType {
case FOLDER
case VIDEO
case SNAPSHOT
}
class MediaItem : DebugPrintable {
var name : String
var path : String
var root: String
var image: UIImage?
var time: NSTimeInterval?
var children: [MediaItem]
var parent: MediaItem?
var type: ItemType
init(name: String, path: String, root: String, type: ItemType) {
self.name = name
self.path = path
self.root = root
self.type = type
children = [MediaItem]()
}
var debugDescription: String {
return root + " " + path + " " + name
}
}

72
kplayer/core/NetworkManager.swift

@ -0,0 +1,72 @@
//
// Created by Marco Schmickler on 24.05.15.
// Copyright (c) 2015 Marco Schmickler. All rights reserved.
//
import Foundation
import Alamofire
class NetworkManager {
static let sharedInstance = NetworkManager()
let baseurl = "http://linkstation/tomcat/media"
func loadRoots() -> AnyObject {
var itemsArray = [];
Alamofire.request(.GET, baseurl + "/service/roots")
.responseString {
(_, _, string, _) in
let f = split(string!) {
$0 == "\r\n"
}
println(string)
println(f)
}
// .response { (request, response, data, error) in
// println(request)
// println(response)
//
// var r = (response as NSString).componentsSeparatedByString("\r\n")
//
// println(error)
// }
return itemsArray;
}
func loadDirs(root: String, completionHandler: ([MediaItem]) -> Void) -> Void {
var itemsArray = [];
Alamofire.request(.GET, baseurl + "/service/dirs" + root)
.responseString {
(_, _, string, _) in
let f = split(string!) {
$0 == "\r\n"
}
let len = count(root)
var res = [MediaItem]()
for s in f {
if (s.hasSuffix(".mp4")) {
let l = count(s)
let name = (s as NSString).lastPathComponent
let pathlen = l - len - count(name)
let path = (s as NSString).substringWithRange(NSMakeRange(len + 1, pathlen - 2))
let i = MediaItem(name: name, path: path, root: root, type: ItemType.VIDEO)
if !name.hasPrefix(".") {
res.append(i)
}
}
}
completionHandler(res)
}
}
func playerURL(item: MediaItem) -> String {
return baseurl + "/service/stream" + item.root + "/" + item.path + "/" + item.name
}
}
Loading…
Cancel
Save