diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0df6d91..0000000 --- a/.gitignore +++ /dev/null @@ -1,172 +0,0 @@ -######################### -# .gitignore file for Xcode4 and Xcode5 Source projects -# -# Apple bugs, waiting for Apple to fix/respond: -# -# 15564624 - what does the xccheckout file in Xcode5 do? Where's the documentation? -# -# Version 2.1 -# For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects -# -# 2013 updates: -# - fixed the broken "save personal Schemes" -# - added line-by-line explanations for EVERYTHING (some were missing) -# -# NB: if you are storing "built" products, this WILL NOT WORK, -# and you should use a different .gitignore (or none at all) -# This file is for SOURCE projects, where there are many extra -# files that we want to exclude -# -######################### - -##### -# OS X temporary files that should never be committed -# -# c.f. http://www.westwind.com/reference/os-x/invisibles.html - -.DS_Store - -# c.f. http://www.westwind.com/reference/os-x/invisibles.html - -.Trashes - -# c.f. http://www.westwind.com/reference/os-x/invisibles.html - -*.swp - -# *.lock - this is used and abused by many editors for many different things. -# For the main ones I use (e.g. Eclipse), it should be excluded -# from source-control, but YMMV - -*.lock - -# -# profile - REMOVED temporarily (on double-checking, this seems incorrect; I can't find it in OS X docs?) -#profile - - -#### -# Xcode temporary files that should never be committed -# -# NB: NIB/XIB files still exist even on Storyboard projects, so we want this... - -*~.nib - - -#### -# Xcode build files - -# -# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" - -DerivedData/ - -# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" - -build/ - - -##### -# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) -# -# This is complicated: -# -# SOMETIMES you need to put this file in version control. -# Apple designed it poorly - if you use "custom executables", they are -# saved in this file. -# 99% of projects do NOT use those, so they do NOT want to version control this file. -# ..but if you're in the 1%, comment out the line "*.pbxuser" - -# .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html - -*.pbxuser - -# .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html - -*.mode1v3 - -# .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html - -*.mode2v3 - -# .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file - -*.perspectivev3 - -# NB: also, whitelist the default ones, some projects need to use these -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - - -#### -# Xcode 4 - semi-personal settings -# -# -# OPTION 1: --------------------------------- -# throw away ALL personal settings (including custom schemes! -# - unless they are "shared") -# -# NB: this is exclusive with OPTION 2 below -xcuserdata - -# OPTION 2: --------------------------------- -# get rid of ALL personal settings, but KEEP SOME OF THEM -# - NB: you must manually uncomment the bits you want to keep -# -# NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X, -# or manually install git over the top of the OS X version -# NB: this is exclusive with OPTION 1 above -# -#xcuserdata/**/* - -# (requires option 2 above): Personal Schemes -# -#!xcuserdata/**/xcschemes/* - -#### -# XCode 4 workspaces - more detailed -# -# Workspaces are important! They are a core feature of Xcode - don't exclude them :) -# -# Workspace layout is quite spammy. For reference: -# -# /(root)/ -# /(project-name).xcodeproj/ -# project.pbxproj -# /project.xcworkspace/ -# contents.xcworkspacedata -# /xcuserdata/ -# /(your name)/xcuserdatad/ -# UserInterfaceState.xcuserstate -# /xcsshareddata/ -# /xcschemes/ -# (shared scheme name).xcscheme -# /xcuserdata/ -# /(your name)/xcuserdatad/ -# (private scheme).xcscheme -# xcschememanagement.plist -# -# - -#### -# Xcode 4 - Deprecated classes -# -# Allegedly, if you manually "deprecate" your classes, they get moved here. -# -# We're using source-control, so this is a "feature" that we do not want! - -*.moved-aside - -#### -# Xcode 5 - VCS file -# The data in this file not represent state of your project. -# If you'll leave this file in git - you will have merge conflicts during -# pull your cahnges to other's repo -# -*.xccheckout - -#### -# UNKNOWN: recommended by others, but I can't discover what these files are -# -# ...none. Everything is now explained. \ No newline at end of file diff --git a/MusicPlayer.xcodeproj/project.pbxproj b/MusicPlayer.xcodeproj/project.pbxproj deleted file mode 100644 index fb1d64d..0000000 --- a/MusicPlayer.xcodeproj/project.pbxproj +++ /dev/null @@ -1,446 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 0270480919C8E08B00FDA1C5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0270480819C8E08B00FDA1C5 /* AppDelegate.swift */; }; - 0270480B19C8E08B00FDA1C5 /* SearchResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0270480A19C8E08B00FDA1C5 /* SearchResultsViewController.swift */; }; - 0270480E19C8E08B00FDA1C5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0270480C19C8E08B00FDA1C5 /* Main.storyboard */; }; - 0270481019C8E08B00FDA1C5 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0270480F19C8E08B00FDA1C5 /* Images.xcassets */; }; - 0270481319C8E08B00FDA1C5 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0270481119C8E08B00FDA1C5 /* LaunchScreen.xib */; }; - 0270481F19C8E08B00FDA1C5 /* MusicPlayerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0270481E19C8E08B00FDA1C5 /* MusicPlayerTests.swift */; }; - 0270482919C8E2E700FDA1C5 /* APIController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0270482819C8E2E700FDA1C5 /* APIController.swift */; }; - 0270482B19C8EC3000FDA1C5 /* Blank52.png in Resources */ = {isa = PBXBuildFile; fileRef = 0270482A19C8EC3000FDA1C5 /* Blank52.png */; }; - 0270482D19C8F35700FDA1C5 /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0270482C19C8F35700FDA1C5 /* Album.swift */; }; - 0270482F19C8F43500FDA1C5 /* DetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0270482E19C8F43500FDA1C5 /* DetailsViewController.swift */; }; - 0270483119C8F6D000FDA1C5 /* Track.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0270483019C8F6D000FDA1C5 /* Track.swift */; }; - 0270483519C8F80000FDA1C5 /* TrackCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0270483419C8F80000FDA1C5 /* TrackCell.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 0270481919C8E08B00FDA1C5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 027047FB19C8E08B00FDA1C5 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 0270480219C8E08B00FDA1C5; - remoteInfo = MusicPlayer; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 0270480319C8E08B00FDA1C5 /* MusicPlayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MusicPlayer.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 0270480719C8E08B00FDA1C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 0270480819C8E08B00FDA1C5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 0270480A19C8E08B00FDA1C5 /* SearchResultsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsViewController.swift; sourceTree = ""; }; - 0270480D19C8E08B00FDA1C5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 0270480F19C8E08B00FDA1C5 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 0270481219C8E08B00FDA1C5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 0270481819C8E08B00FDA1C5 /* MusicPlayerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MusicPlayerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 0270481D19C8E08B00FDA1C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 0270481E19C8E08B00FDA1C5 /* MusicPlayerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicPlayerTests.swift; sourceTree = ""; }; - 0270482819C8E2E700FDA1C5 /* APIController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APIController.swift; sourceTree = ""; }; - 0270482A19C8EC3000FDA1C5 /* Blank52.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Blank52.png; sourceTree = ""; }; - 0270482C19C8F35700FDA1C5 /* Album.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Album.swift; sourceTree = ""; }; - 0270482E19C8F43500FDA1C5 /* DetailsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailsViewController.swift; sourceTree = ""; }; - 0270483019C8F6D000FDA1C5 /* Track.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Track.swift; sourceTree = ""; }; - 0270483419C8F80000FDA1C5 /* TrackCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrackCell.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 0270480019C8E08B00FDA1C5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 0270481519C8E08B00FDA1C5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 027047FA19C8E08B00FDA1C5 = { - isa = PBXGroup; - children = ( - 0270480519C8E08B00FDA1C5 /* MusicPlayer */, - 0270481B19C8E08B00FDA1C5 /* MusicPlayerTests */, - 0270480419C8E08B00FDA1C5 /* Products */, - ); - sourceTree = ""; - }; - 0270480419C8E08B00FDA1C5 /* Products */ = { - isa = PBXGroup; - children = ( - 0270480319C8E08B00FDA1C5 /* MusicPlayer.app */, - 0270481819C8E08B00FDA1C5 /* MusicPlayerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 0270480519C8E08B00FDA1C5 /* MusicPlayer */ = { - isa = PBXGroup; - children = ( - 0270482A19C8EC3000FDA1C5 /* Blank52.png */, - 0270480819C8E08B00FDA1C5 /* AppDelegate.swift */, - 0270480A19C8E08B00FDA1C5 /* SearchResultsViewController.swift */, - 0270480C19C8E08B00FDA1C5 /* Main.storyboard */, - 0270480F19C8E08B00FDA1C5 /* Images.xcassets */, - 0270481119C8E08B00FDA1C5 /* LaunchScreen.xib */, - 0270480619C8E08B00FDA1C5 /* Supporting Files */, - 0270482819C8E2E700FDA1C5 /* APIController.swift */, - 0270482C19C8F35700FDA1C5 /* Album.swift */, - 0270482E19C8F43500FDA1C5 /* DetailsViewController.swift */, - 0270483019C8F6D000FDA1C5 /* Track.swift */, - 0270483419C8F80000FDA1C5 /* TrackCell.swift */, - ); - path = MusicPlayer; - sourceTree = ""; - }; - 0270480619C8E08B00FDA1C5 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 0270480719C8E08B00FDA1C5 /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 0270481B19C8E08B00FDA1C5 /* MusicPlayerTests */ = { - isa = PBXGroup; - children = ( - 0270481E19C8E08B00FDA1C5 /* MusicPlayerTests.swift */, - 0270481C19C8E08B00FDA1C5 /* Supporting Files */, - ); - path = MusicPlayerTests; - sourceTree = ""; - }; - 0270481C19C8E08B00FDA1C5 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 0270481D19C8E08B00FDA1C5 /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 0270480219C8E08B00FDA1C5 /* MusicPlayer */ = { - isa = PBXNativeTarget; - buildConfigurationList = 0270482219C8E08B00FDA1C5 /* Build configuration list for PBXNativeTarget "MusicPlayer" */; - buildPhases = ( - 027047FF19C8E08B00FDA1C5 /* Sources */, - 0270480019C8E08B00FDA1C5 /* Frameworks */, - 0270480119C8E08B00FDA1C5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = MusicPlayer; - productName = MusicPlayer; - productReference = 0270480319C8E08B00FDA1C5 /* MusicPlayer.app */; - productType = "com.apple.product-type.application"; - }; - 0270481719C8E08B00FDA1C5 /* MusicPlayerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 0270482519C8E08B00FDA1C5 /* Build configuration list for PBXNativeTarget "MusicPlayerTests" */; - buildPhases = ( - 0270481419C8E08B00FDA1C5 /* Sources */, - 0270481519C8E08B00FDA1C5 /* Frameworks */, - 0270481619C8E08B00FDA1C5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 0270481A19C8E08B00FDA1C5 /* PBXTargetDependency */, - ); - name = MusicPlayerTests; - productName = MusicPlayerTests; - productReference = 0270481819C8E08B00FDA1C5 /* MusicPlayerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 027047FB19C8E08B00FDA1C5 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0600; - ORGANIZATIONNAME = "JQ Software LLC"; - TargetAttributes = { - 0270480219C8E08B00FDA1C5 = { - CreatedOnToolsVersion = 6.0; - }; - 0270481719C8E08B00FDA1C5 = { - CreatedOnToolsVersion = 6.0; - TestTargetID = 0270480219C8E08B00FDA1C5; - }; - }; - }; - buildConfigurationList = 027047FE19C8E08B00FDA1C5 /* Build configuration list for PBXProject "MusicPlayer" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 027047FA19C8E08B00FDA1C5; - productRefGroup = 0270480419C8E08B00FDA1C5 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 0270480219C8E08B00FDA1C5 /* MusicPlayer */, - 0270481719C8E08B00FDA1C5 /* MusicPlayerTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 0270480119C8E08B00FDA1C5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 0270480E19C8E08B00FDA1C5 /* Main.storyboard in Resources */, - 0270482B19C8EC3000FDA1C5 /* Blank52.png in Resources */, - 0270481319C8E08B00FDA1C5 /* LaunchScreen.xib in Resources */, - 0270481019C8E08B00FDA1C5 /* Images.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 0270481619C8E08B00FDA1C5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 027047FF19C8E08B00FDA1C5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 0270483519C8F80000FDA1C5 /* TrackCell.swift in Sources */, - 0270480B19C8E08B00FDA1C5 /* SearchResultsViewController.swift in Sources */, - 0270480919C8E08B00FDA1C5 /* AppDelegate.swift in Sources */, - 0270482919C8E2E700FDA1C5 /* APIController.swift in Sources */, - 0270482D19C8F35700FDA1C5 /* Album.swift in Sources */, - 0270482F19C8F43500FDA1C5 /* DetailsViewController.swift in Sources */, - 0270483119C8F6D000FDA1C5 /* Track.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 0270481419C8E08B00FDA1C5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 0270481F19C8E08B00FDA1C5 /* MusicPlayerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 0270481A19C8E08B00FDA1C5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 0270480219C8E08B00FDA1C5 /* MusicPlayer */; - targetProxy = 0270481919C8E08B00FDA1C5 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 0270480C19C8E08B00FDA1C5 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 0270480D19C8E08B00FDA1C5 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 0270481119C8E08B00FDA1C5 /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 0270481219C8E08B00FDA1C5 /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 0270482019C8E08B00FDA1C5 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 0270482119C8E08B00FDA1C5 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 0270482319C8E08B00FDA1C5 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = MusicPlayer/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 0270482419C8E08B00FDA1C5 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = MusicPlayer/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 0270482619C8E08B00FDA1C5 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = MusicPlayerTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MusicPlayer.app/MusicPlayer"; - }; - name = Debug; - }; - 0270482719C8E08B00FDA1C5 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); - INFOPLIST_FILE = MusicPlayerTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MusicPlayer.app/MusicPlayer"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 027047FE19C8E08B00FDA1C5 /* Build configuration list for PBXProject "MusicPlayer" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 0270482019C8E08B00FDA1C5 /* Debug */, - 0270482119C8E08B00FDA1C5 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 0270482219C8E08B00FDA1C5 /* Build configuration list for PBXNativeTarget "MusicPlayer" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 0270482319C8E08B00FDA1C5 /* Debug */, - 0270482419C8E08B00FDA1C5 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 0270482519C8E08B00FDA1C5 /* Build configuration list for PBXNativeTarget "MusicPlayerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 0270482619C8E08B00FDA1C5 /* Debug */, - 0270482719C8E08B00FDA1C5 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 027047FB19C8E08B00FDA1C5 /* Project object */; -} diff --git a/MusicPlayer/Album.swift b/MusicPlayer/Album.swift deleted file mode 100644 index 466b5fb..0000000 --- a/MusicPlayer/Album.swift +++ /dev/null @@ -1,79 +0,0 @@ -// -// Album.swift -// MusicPlayer -// -// Created by Jameson Quave on 9/16/14. -// Copyright (c) 2014 JQ Software LLC. All rights reserved. -// - -import Foundation - -class Album { - var title: String - var price: String - var thumbnailImageURL: String - var largeImageURL: String - var itemURL: String - var artistURL: String - var collectionId: Int - - init(name: String, price: String, thumbnailImageURL: String, largeImageURL: String, itemURL: String, artistURL: String, collectionId: Int) { - self.title = name - self.price = price - self.thumbnailImageURL = thumbnailImageURL - self.largeImageURL = largeImageURL - self.itemURL = itemURL - self.artistURL = artistURL - self.collectionId = collectionId - } - - class func albumsWithJSON(allResults: NSArray) -> [Album] { - - // Create an empty array of Albums to append to from this list - var albums = [Album]() - - // Store the results in our table data array - if allResults.count>0 { - - // Sometimes iTunes returns a collection, not a track, so we check both for the 'name' - for result in allResults { - - var name = result["trackName"] as? String - if name == nil { - name = result["collectionName"] as? String - } - - // Sometimes price comes in as formattedPrice, sometimes as collectionPrice.. and sometimes it's a float instead of a string. Hooray! - var price = result["formattedPrice"] as? String - if price == nil { - price = result["collectionPrice"] as? String - if price == nil { - var priceFloat: Float? = result["collectionPrice"] as? Float - var nf: NSNumberFormatter = NSNumberFormatter() - nf.maximumFractionDigits = 2 - if priceFloat != nil { - price = "$"+nf.stringFromNumber(priceFloat!) - } - } - } - - let thumbnailURL = result["artworkUrl60"] as? String ?? "" - let imageURL = result["artworkUrl100"] as? String ?? "" - let artistURL = result["artistViewUrl"] as? String ?? "" - - var itemURL = result["collectionViewUrl"] as? String - if itemURL == nil { - itemURL = result["trackViewUrl"] as? String - } - - var collectionId = result["collectionId"] as? Int - - var newAlbum = Album(name: name!, price: price!, thumbnailImageURL: thumbnailURL, largeImageURL: imageURL, itemURL: itemURL!, artistURL: artistURL, collectionId: collectionId!) - albums.append(newAlbum) - - } - } - return albums - } - -} \ No newline at end of file diff --git a/MusicPlayer/Base.lproj/LaunchScreen.xib b/MusicPlayer/Base.lproj/LaunchScreen.xib deleted file mode 100644 index e3c2ed9..0000000 --- a/MusicPlayer/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MusicPlayer/Base.lproj/Main.storyboard b/MusicPlayer/Base.lproj/Main.storyboard deleted file mode 100644 index a257ec7..0000000 --- a/MusicPlayer/Base.lproj/Main.storyboard +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MusicPlayer/Blank52.png b/MusicPlayer/Blank52.png deleted file mode 100644 index c6ca077..0000000 Binary files a/MusicPlayer/Blank52.png and /dev/null differ diff --git a/MusicPlayer/DetailsViewController.swift b/MusicPlayer/DetailsViewController.swift deleted file mode 100644 index 677a102..0000000 --- a/MusicPlayer/DetailsViewController.swift +++ /dev/null @@ -1,78 +0,0 @@ -// -// DetailsViewController.swift -// MusicPlayer -// -// Created by Jameson Quave on 9/16/14. -// Copyright (c) 2014 JQ Software LLC. All rights reserved. -// - -import UIKit -import MediaPlayer - -class DetailsViewController: UIViewController, APIControllerProtocol, UITableViewDelegate, UITableViewDataSource { - - var album: Album? - var tracks = [Track]() - - @IBOutlet weak var titleLabel: UILabel! - @IBOutlet weak var albumCover: UIImageView! - @IBOutlet weak var tracksTableView: UITableView! - lazy var api : APIController = APIController(delegate: self) - var mediaPlayer: MPMoviePlayerController = MPMoviePlayerController() - - required init(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - } - - override func viewDidLoad() { - super.viewDidLoad() - titleLabel.text = self.album?.title - albumCover.image = UIImage(data: NSData(contentsOfURL: NSURL(string: self.album!.largeImageURL))) - - if self.album != nil { - api.lookupAlbum(self.album!.collectionId) - } - } - - // MARK: UITableViewDataSource - func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return tracks.count - } - - func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCellWithIdentifier("TrackCell") as TrackCell - let track = tracks[indexPath.row] - cell.titleLabel.text = track.title - cell.playIcon.text = "▶️" - - return cell - } - - func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { - var track = tracks[indexPath.row] - mediaPlayer.stop() - mediaPlayer.contentURL = NSURL(string: track.previewUrl) - mediaPlayer.play() - if let cell = tableView.cellForRowAtIndexPath(indexPath) as? TrackCell { - cell.playIcon.text = "◾️" - } - } - - func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { - cell.layer.transform = CATransform3DMakeScale(0.1,0.1,1) - UIView.animateWithDuration(0.25, animations: { - cell.layer.transform = CATransform3DMakeScale(1,1,1) - }) - } - - // MARK: APIControllerProtocol - func didReceiveAPIResults(results: NSDictionary) { - var resultsArr: NSArray = results["results"] as NSArray - dispatch_async(dispatch_get_main_queue(), { - self.tracks = Track.tracksWithJSON(resultsArr) - self.tracksTableView.reloadData() - UIApplication.sharedApplication().networkActivityIndicatorVisible = false - }) - } - -} \ No newline at end of file diff --git a/MusicPlayer/SearchResultsViewController.swift b/MusicPlayer/SearchResultsViewController.swift deleted file mode 100644 index 8e9cbfa..0000000 --- a/MusicPlayer/SearchResultsViewController.swift +++ /dev/null @@ -1,119 +0,0 @@ -// -// ViewController.swift -// MusicPlayer -// -// Created by Jameson Quave on 9/16/14. -// Copyright (c) 2014 JQ Software LLC. All rights reserved. -// - -import UIKit - -class SearchResultsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, APIControllerProtocol { - - @IBOutlet var appsTableView : UITableView? - var albums = [Album]() - var api : APIController? - var imageCache = [String : UIImage]() - let kCellIdentifier: String = "SearchResultCell" - - override func viewDidLoad() { - super.viewDidLoad() - api = APIController(delegate: self) - UIApplication.sharedApplication().networkActivityIndicatorVisible = true - api!.searchItunesFor("Beatles") - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - - // MARK: UITableViewDataSource - - func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return albums.count - } - - func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - - let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as UITableViewCell - - let album = self.albums[indexPath.row] - cell.textLabel?.text = album.title - cell.imageView?.image = UIImage(named: "Blank52") - - // Get the formatted price string for display in the subtitle - let formattedPrice = album.price - - // Grab the artworkUrl60 key to get an image URL for the app's thumbnail - let urlString = album.thumbnailImageURL - - // Check our image cache for the existing key. This is just a dictionary of UIImages - //var image: UIImage? = self.imageCache.valueForKey(urlString) as? UIImage - var image = self.imageCache[urlString] - - - if( image == nil ) { - // If the image does not exist, we need to download it - var imgURL: NSURL = NSURL(string: urlString) - - // Download an NSData representation of the image at the URL - let request: NSURLRequest = NSURLRequest(URL: imgURL) - NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in - if error == nil { - image = UIImage(data: data) - - // Store the image in to our cache - self.imageCache[urlString] = image - dispatch_async(dispatch_get_main_queue(), { - if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) { - cellToUpdate.imageView?.image = image - } - }) - } - else { - println("Error: \(error.localizedDescription)") - } - }) - - } - else { - dispatch_async(dispatch_get_main_queue(), { - if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) { - cellToUpdate.imageView?.image = image - } - }) - } - - cell.detailTextLabel?.text = formattedPrice - - return cell - } - - func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { - cell.layer.transform = CATransform3DMakeScale(0.1,0.1,1) - UIView.animateWithDuration(0.25, animations: { - cell.layer.transform = CATransform3DMakeScale(1,1,1) - }) - } - - - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { - var detailsViewController: DetailsViewController = segue.destinationViewController as DetailsViewController - var albumIndex = appsTableView!.indexPathForSelectedRow()!.row - var selectedAlbum = self.albums[albumIndex] - detailsViewController.album = selectedAlbum - } - - func didReceiveAPIResults(results: NSDictionary) { - var resultsArr: NSArray = results["results"] as NSArray - dispatch_async(dispatch_get_main_queue(), { - self.albums = Album.albumsWithJSON(resultsArr) - self.appsTableView!.reloadData() - UIApplication.sharedApplication().networkActivityIndicatorVisible = false - }) - } - -} - diff --git a/MusicPlayer/Track.swift b/MusicPlayer/Track.swift deleted file mode 100644 index 19f03d0..0000000 --- a/MusicPlayer/Track.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// Track.swift -// MusicPlayer -// -// Created by Jameson Quave on 9/16/14. -// Copyright (c) 2014 JQ Software LLC. All rights reserved. -// - -import Foundation -class Track { - - var title: String - var price: String - var previewUrl: String - var tracks = [Track]() - - init(title: String, price: String, previewUrl: String) { - self.title = title - self.price = price - self.previewUrl = previewUrl - } - - class func tracksWithJSON(allResults: NSArray) -> [Track] { - - var tracks = [Track]() - - if allResults.count>0 { - for trackInfo in allResults { - // Create the track - if let kind = trackInfo["kind"] as? String { - if kind=="song" { - - var trackPrice = trackInfo["trackPrice"] as? String - var trackTitle = trackInfo["trackName"] as? String - var trackPreviewUrl = trackInfo["previewUrl"] as? String - - if(trackTitle == nil) { - trackTitle = "Unknown" - } - else if(trackPrice == nil) { - println("No trackPrice in \(trackInfo)") - trackPrice = "?" - } - else if(trackPreviewUrl == nil) { - trackPreviewUrl = "" - } - - var track = Track(title: trackTitle!, price: trackPrice!, previewUrl: trackPreviewUrl!) - tracks.append(track) - - } - } - } - } - return tracks - } - -} \ No newline at end of file diff --git a/MusicPlayer/TrackCell.swift b/MusicPlayer/TrackCell.swift deleted file mode 100644 index 0faab52..0000000 --- a/MusicPlayer/TrackCell.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// TrackCell.swift -// MusicPlayer -// -// Created by Jameson Quave on 9/16/14. -// Copyright (c) 2014 JQ Software LLC. All rights reserved. -// - -import UIKit - -class TrackCell: UITableViewCell { - - @IBOutlet weak var playIcon: UILabel! - @IBOutlet weak var titleLabel: UILabel! - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code - } - - override func setSelected(selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state - } - -} diff --git a/SwiftTutorial.xcodeproj/project.pbxproj b/SwiftTutorial.xcodeproj/project.pbxproj new file mode 100644 index 0000000..2304254 --- /dev/null +++ b/SwiftTutorial.xcodeproj/project.pbxproj @@ -0,0 +1,438 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 021C0E56194F506F0005B787 /* Track.swift in Sources */ = {isa = PBXBuildFile; fileRef = 021C0E55194F506F0005B787 /* Track.swift */; }; + 021C0E58194F51610005B787 /* TrackCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 021C0E57194F51610005B787 /* TrackCell.swift */; }; + 0256BB50194F3F38003E2942 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB4F194F3F38003E2942 /* AppDelegate.swift */; }; + 0256BB52194F3F38003E2942 /* SearchResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB51194F3F38003E2942 /* SearchResultsViewController.swift */; }; + 0256BB55194F3F38003E2942 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0256BB53194F3F38003E2942 /* Main.storyboard */; }; + 0256BB57194F3F38003E2942 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0256BB56194F3F38003E2942 /* Images.xcassets */; }; + 0256BB63194F3F38003E2942 /* SwiftTutorialTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB62194F3F38003E2942 /* SwiftTutorialTests.swift */; }; + 0256BB6D194F41F5003E2942 /* APIController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB6C194F41F5003E2942 /* APIController.swift */; }; + 0256BB6F194F4852003E2942 /* Blank52.png in Resources */ = {isa = PBXBuildFile; fileRef = 0256BB6E194F4852003E2942 /* Blank52.png */; }; + 0256BB71194F4A9F003E2942 /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB70194F4A9F003E2942 /* Album.swift */; }; + 0256BB73194F4B47003E2942 /* DetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB72194F4B47003E2942 /* DetailsViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 0256BB5D194F3F38003E2942 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0256BB42194F3F38003E2942 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0256BB49194F3F38003E2942; + remoteInfo = SwiftTutorial; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 021C0E55194F506F0005B787 /* Track.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Track.swift; sourceTree = ""; }; + 021C0E57194F51610005B787 /* TrackCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrackCell.swift; sourceTree = ""; }; + 0256BB4A194F3F38003E2942 /* SwiftTutorial.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftTutorial.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0256BB4E194F3F38003E2942 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 0256BB4F194F3F38003E2942 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 0256BB51194F3F38003E2942 /* SearchResultsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsViewController.swift; sourceTree = ""; }; + 0256BB54194F3F38003E2942 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 0256BB56194F3F38003E2942 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 0256BB5C194F3F38003E2942 /* SwiftTutorialTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftTutorialTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 0256BB61194F3F38003E2942 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 0256BB62194F3F38003E2942 /* SwiftTutorialTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftTutorialTests.swift; sourceTree = ""; }; + 0256BB6C194F41F5003E2942 /* APIController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APIController.swift; sourceTree = ""; }; + 0256BB6E194F4852003E2942 /* Blank52.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Blank52.png; sourceTree = ""; }; + 0256BB70194F4A9F003E2942 /* Album.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Album.swift; sourceTree = ""; }; + 0256BB72194F4B47003E2942 /* DetailsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailsViewController.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 0256BB47194F3F38003E2942 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0256BB59194F3F38003E2942 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0256BB41194F3F38003E2942 = { + isa = PBXGroup; + children = ( + 0256BB4C194F3F38003E2942 /* SwiftTutorial */, + 0256BB5F194F3F38003E2942 /* SwiftTutorialTests */, + 0256BB4B194F3F38003E2942 /* Products */, + ); + sourceTree = ""; + }; + 0256BB4B194F3F38003E2942 /* Products */ = { + isa = PBXGroup; + children = ( + 0256BB4A194F3F38003E2942 /* SwiftTutorial.app */, + 0256BB5C194F3F38003E2942 /* SwiftTutorialTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 0256BB4C194F3F38003E2942 /* SwiftTutorial */ = { + isa = PBXGroup; + children = ( + 0256BB6E194F4852003E2942 /* Blank52.png */, + 0256BB4F194F3F38003E2942 /* AppDelegate.swift */, + 0256BB51194F3F38003E2942 /* SearchResultsViewController.swift */, + 0256BB53194F3F38003E2942 /* Main.storyboard */, + 0256BB56194F3F38003E2942 /* Images.xcassets */, + 0256BB4D194F3F38003E2942 /* Supporting Files */, + 0256BB6C194F41F5003E2942 /* APIController.swift */, + 0256BB70194F4A9F003E2942 /* Album.swift */, + 0256BB72194F4B47003E2942 /* DetailsViewController.swift */, + 021C0E55194F506F0005B787 /* Track.swift */, + 021C0E57194F51610005B787 /* TrackCell.swift */, + ); + path = SwiftTutorial; + sourceTree = ""; + }; + 0256BB4D194F3F38003E2942 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 0256BB4E194F3F38003E2942 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 0256BB5F194F3F38003E2942 /* SwiftTutorialTests */ = { + isa = PBXGroup; + children = ( + 0256BB62194F3F38003E2942 /* SwiftTutorialTests.swift */, + 0256BB60194F3F38003E2942 /* Supporting Files */, + ); + path = SwiftTutorialTests; + sourceTree = ""; + }; + 0256BB60194F3F38003E2942 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 0256BB61194F3F38003E2942 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 0256BB49194F3F38003E2942 /* SwiftTutorial */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0256BB66194F3F38003E2942 /* Build configuration list for PBXNativeTarget "SwiftTutorial" */; + buildPhases = ( + 0256BB46194F3F38003E2942 /* Sources */, + 0256BB47194F3F38003E2942 /* Frameworks */, + 0256BB48194F3F38003E2942 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwiftTutorial; + productName = SwiftTutorial; + productReference = 0256BB4A194F3F38003E2942 /* SwiftTutorial.app */; + productType = "com.apple.product-type.application"; + }; + 0256BB5B194F3F38003E2942 /* SwiftTutorialTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0256BB69194F3F38003E2942 /* Build configuration list for PBXNativeTarget "SwiftTutorialTests" */; + buildPhases = ( + 0256BB58194F3F38003E2942 /* Sources */, + 0256BB59194F3F38003E2942 /* Frameworks */, + 0256BB5A194F3F38003E2942 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 0256BB5E194F3F38003E2942 /* PBXTargetDependency */, + ); + name = SwiftTutorialTests; + productName = SwiftTutorialTests; + productReference = 0256BB5C194F3F38003E2942 /* SwiftTutorialTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0256BB42194F3F38003E2942 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0600; + ORGANIZATIONNAME = "JQ Software LLC"; + TargetAttributes = { + 0256BB49194F3F38003E2942 = { + CreatedOnToolsVersion = 6.0; + }; + 0256BB5B194F3F38003E2942 = { + CreatedOnToolsVersion = 6.0; + TestTargetID = 0256BB49194F3F38003E2942; + }; + }; + }; + buildConfigurationList = 0256BB45194F3F38003E2942 /* Build configuration list for PBXProject "SwiftTutorial" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 0256BB41194F3F38003E2942; + productRefGroup = 0256BB4B194F3F38003E2942 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 0256BB49194F3F38003E2942 /* SwiftTutorial */, + 0256BB5B194F3F38003E2942 /* SwiftTutorialTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 0256BB48194F3F38003E2942 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0256BB6F194F4852003E2942 /* Blank52.png in Resources */, + 0256BB55194F3F38003E2942 /* Main.storyboard in Resources */, + 0256BB57194F3F38003E2942 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0256BB5A194F3F38003E2942 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 0256BB46194F3F38003E2942 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 021C0E58194F51610005B787 /* TrackCell.swift in Sources */, + 0256BB52194F3F38003E2942 /* SearchResultsViewController.swift in Sources */, + 0256BB50194F3F38003E2942 /* AppDelegate.swift in Sources */, + 0256BB6D194F41F5003E2942 /* APIController.swift in Sources */, + 0256BB71194F4A9F003E2942 /* Album.swift in Sources */, + 0256BB73194F4B47003E2942 /* DetailsViewController.swift in Sources */, + 021C0E56194F506F0005B787 /* Track.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0256BB58194F3F38003E2942 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0256BB63194F3F38003E2942 /* SwiftTutorialTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 0256BB5E194F3F38003E2942 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0256BB49194F3F38003E2942 /* SwiftTutorial */; + targetProxy = 0256BB5D194F3F38003E2942 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 0256BB53194F3F38003E2942 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 0256BB54194F3F38003E2942 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 0256BB64194F3F38003E2942 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + METAL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 0256BB65194F3F38003E2942 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + METAL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 0256BB67194F3F38003E2942 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + INFOPLIST_FILE = SwiftTutorial/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 0256BB68194F3F38003E2942 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + INFOPLIST_FILE = SwiftTutorial/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 0256BB6A194F3F38003E2942 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/SwiftTutorial.app/SwiftTutorial"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = SwiftTutorialTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + METAL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + }; + name = Debug; + }; + 0256BB6B194F3F38003E2942 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/SwiftTutorial.app/SwiftTutorial"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = SwiftTutorialTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + METAL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0256BB45194F3F38003E2942 /* Build configuration list for PBXProject "SwiftTutorial" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0256BB64194F3F38003E2942 /* Debug */, + 0256BB65194F3F38003E2942 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0256BB66194F3F38003E2942 /* Build configuration list for PBXNativeTarget "SwiftTutorial" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0256BB67194F3F38003E2942 /* Debug */, + 0256BB68194F3F38003E2942 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0256BB69194F3F38003E2942 /* Build configuration list for PBXNativeTarget "SwiftTutorialTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0256BB6A194F3F38003E2942 /* Debug */, + 0256BB6B194F3F38003E2942 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0256BB42194F3F38003E2942 /* Project object */; +} diff --git a/MusicPlayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/SwiftTutorial.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 68% rename from MusicPlayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to SwiftTutorial.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 404a2e3..fbcbb6e 100644 --- a/MusicPlayer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/SwiftTutorial.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:SwiftTutorial.xcodeproj"> diff --git a/SwiftTutorial.xcodeproj/xcuserdata/jquave.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/SwiftTutorial.xcodeproj/xcuserdata/jquave.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..2da389e --- /dev/null +++ b/SwiftTutorial.xcodeproj/xcuserdata/jquave.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/SwiftTutorial.xcodeproj/xcuserdata/jquave.xcuserdatad/xcschemes/SwiftTutorial.xcscheme b/SwiftTutorial.xcodeproj/xcuserdata/jquave.xcuserdatad/xcschemes/SwiftTutorial.xcscheme new file mode 100644 index 0000000..0be1e07 --- /dev/null +++ b/SwiftTutorial.xcodeproj/xcuserdata/jquave.xcuserdatad/xcschemes/SwiftTutorial.xcscheme @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SwiftTutorial.xcodeproj/xcuserdata/jquave.xcuserdatad/xcschemes/xcschememanagement.plist b/SwiftTutorial.xcodeproj/xcuserdata/jquave.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..05e9e8c --- /dev/null +++ b/SwiftTutorial.xcodeproj/xcuserdata/jquave.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,27 @@ + + + + + SchemeUserState + + SwiftTutorial.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 0256BB49194F3F38003E2942 + + primary + + + 0256BB5B194F3F38003E2942 + + primary + + + + + diff --git a/MusicPlayer/APIController.swift b/SwiftTutorial/APIController.swift similarity index 69% rename from MusicPlayer/APIController.swift rename to SwiftTutorial/APIController.swift index aec4266..c676999 100644 --- a/MusicPlayer/APIController.swift +++ b/SwiftTutorial/APIController.swift @@ -1,60 +1,59 @@ // // APIController.swift -// MusicPlayer +// SwiftTutorial // -// Created by Jameson Quave on 9/16/14. +// Created by Jameson Quave on 6/16/14. // Copyright (c) 2014 JQ Software LLC. All rights reserved. // -import Foundation +import UIKit protocol APIControllerProtocol { func didReceiveAPIResults(results: NSDictionary) } -class APIController { - - var delegate: APIControllerProtocol +class APIController: NSObject { + var delegate: APIControllerProtocol? - init(delegate: APIControllerProtocol) { + init(delegate: APIControllerProtocol?) { self.delegate = delegate } + func searchItunesFor(searchTerm: String) { + + // The iTunes API wants multiple terms separated by + symbols, so replace spaces with + signs + let itunesSearchTerm = searchTerm.stringByReplacingOccurrencesOfString(" ", withString: "+", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil) + + // Now escape anything else that isn't URL-friendly + let escapedSearchTerm = itunesSearchTerm.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) + let urlPath = "https://itunes.apple.com/search?term=\(escapedSearchTerm)&media=music&entity=album" + get(urlPath) + } + + func lookupAlbum(collectionId: Int) { + get("https://itunes.apple.com/lookup?id=\(collectionId)&entity=song") + } + func get(path: String) { let url = NSURL(string: path) let session = NSURLSession.sharedSession() let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in println("Task completed") - if(error != nil) { + if(error) { // If there is an error in the web request, print it to the console println(error.localizedDescription) } var err: NSError? var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary - if(err != nil) { + if(err?) { // If there is an error parsing JSON, print it to the console println("JSON Error \(err!.localizedDescription)") } - let results: NSArray = jsonResult["results"] as NSArray - self.delegate.didReceiveAPIResults(jsonResult) // THIS IS THE NEW LINE!! - }) + var results = jsonResult["results"] as NSArray + // Now send the JSON result to our delegate object + self.delegate?.didReceiveAPIResults(jsonResult) + }) task.resume() } - func searchItunesFor(searchTerm: String) { - - // The iTunes API wants multiple terms separated by + symbols, so replace spaces with + signs - let itunesSearchTerm = searchTerm.stringByReplacingOccurrencesOfString(" ", withString: "+", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil) - - // Now escape anything else that isn't URL-friendly - if let escapedSearchTerm = itunesSearchTerm.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) { - let urlPath = "https://itunes.apple.com/search?term=\(escapedSearchTerm)&media=music&entity=album" - get(urlPath) - } - } - - func lookupAlbum(collectionId: Int) { - get("https://itunes.apple.com/lookup?id=\(collectionId)&entity=song") - } - -} \ No newline at end of file +} diff --git a/SwiftTutorial/Album.swift b/SwiftTutorial/Album.swift new file mode 100644 index 0000000..9777afd --- /dev/null +++ b/SwiftTutorial/Album.swift @@ -0,0 +1,27 @@ +// +// Album.swift +// SwiftTutorial +// +// Created by Jameson Quave on 6/16/14. +// Copyright (c) 2014 JQ Software LLC. All rights reserved. +// + +class Album { + var title: String? + var price: String? + var thumbnailImageURL: String? + var largeImageURL: String? + var itemURL: String? + var artistURL: String? + var collectionId: Int? + + init(name: String!, price: String!, thumbnailImageURL: String!, largeImageURL: String!, itemURL: String!, artistURL: String!, collectionId: Int?) { + self.title = name + self.price = price + self.thumbnailImageURL = thumbnailImageURL + self.largeImageURL = largeImageURL + self.itemURL = itemURL + self.artistURL = artistURL + self.collectionId = collectionId + } +} \ No newline at end of file diff --git a/MusicPlayer/AppDelegate.swift b/SwiftTutorial/AppDelegate.swift similarity index 90% rename from MusicPlayer/AppDelegate.swift rename to SwiftTutorial/AppDelegate.swift index aeb9c03..2b6d79f 100644 --- a/MusicPlayer/AppDelegate.swift +++ b/SwiftTutorial/AppDelegate.swift @@ -1,8 +1,8 @@ // // AppDelegate.swift -// MusicPlayer +// SwiftTutorial // -// Created by Jameson Quave on 9/16/14. +// Created by Jameson Quave on 6/16/14. // Copyright (c) 2014 JQ Software LLC. All rights reserved. // @@ -10,12 +10,12 @@ import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - + var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { - println("Hello World!") + func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { + // Override point for customization after application launch. return true } diff --git a/SwiftTutorial/Base.lproj/Main.storyboard b/SwiftTutorial/Base.lproj/Main.storyboard new file mode 100644 index 0000000..09a9ebb --- /dev/null +++ b/SwiftTutorial/Base.lproj/Main.storyboard @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SwiftTutorial/Blank52.png b/SwiftTutorial/Blank52.png new file mode 100644 index 0000000..132e186 Binary files /dev/null and b/SwiftTutorial/Blank52.png differ diff --git a/SwiftTutorial/DetailsViewController.swift b/SwiftTutorial/DetailsViewController.swift new file mode 100644 index 0000000..a03e277 --- /dev/null +++ b/SwiftTutorial/DetailsViewController.swift @@ -0,0 +1,90 @@ +// +// DetailsViewController.swift +// SwiftTutorial +// +// Created by Jameson Quave on 6/16/14. +// Copyright (c) 2014 JQ Software LLC. All rights reserved. +// + +import UIKit +import MediaPlayer +import QuartzCore + +class DetailsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, APIControllerProtocol { + + var mediaPlayer: MPMoviePlayerController = MPMoviePlayerController() + var tracks: Track[] = [] + + @IBOutlet var albumCover : UIImageView + @IBOutlet var titleLabel : UILabel + @IBOutlet var tracksTableView : UITableView + + @lazy var api: APIController = APIController(delegate: self) + + var album: Album? + + init(coder aDecoder: NSCoder!) { + super.init(coder: aDecoder) + } + + override func viewDidLoad() { + super.viewDidLoad() + titleLabel.text = self.album?.title + albumCover.image = UIImage(data: NSData(contentsOfURL: NSURL(string: self.album?.largeImageURL))) + + // Load in tracks + if self.album?.collectionId? { + api.lookupAlbum(self.album!.collectionId!) + } + } + + func didReceiveAPIResults(results: NSDictionary) { + if let allResults = results["results"] as? NSDictionary[] { + for trackInfo in allResults { + // Create the track + if let kind = trackInfo["kind"] as? String { + if kind=="song" { + var track = Track(dict: trackInfo) + tracks.append(track) + } + } + } + } + dispatch_async(dispatch_get_main_queue(), { + self.tracksTableView.reloadData() + }) + } + + func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int { + return tracks.count + } + + func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { + var cell = tableView.dequeueReusableCellWithIdentifier("TrackCell") as TrackCell + + var track = tracks[indexPath.row] + cell.titleLabel.text = track.title + cell.playIcon.text = "▶️" + + return cell + } + + func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) { + var track = tracks[indexPath.row] + mediaPlayer.stop() + mediaPlayer.contentURL = NSURL(string: track.previewUrl) + mediaPlayer.play() + if let cell = tableView.cellForRowAtIndexPath(indexPath) as? TrackCell { + cell.playIcon.text = "YOUR_STOP_ICON" + } + } + + func tableView(tableView: UITableView!, willDisplayCell cell: UITableViewCell!, forRowAtIndexPath indexPath: NSIndexPath!) { + cell.layer.transform = CATransform3DMakeScale(0.1,0.1,1) + UIView.animateWithDuration(0.25, animations: { + cell.layer.transform = CATransform3DMakeScale(1,1,1) + }) + } + + +} \ No newline at end of file diff --git a/MusicPlayer/Images.xcassets/AppIcon.appiconset/Contents.json b/SwiftTutorial/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 56% rename from MusicPlayer/Images.xcassets/AppIcon.appiconset/Contents.json rename to SwiftTutorial/Images.xcassets/AppIcon.appiconset/Contents.json index 118c98f..a396706 100644 --- a/MusicPlayer/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/SwiftTutorial/Images.xcassets/AppIcon.appiconset/Contents.json @@ -5,30 +5,15 @@ "size" : "29x29", "scale" : "2x" }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" } ], "info" : { diff --git a/SwiftTutorial/Images.xcassets/LaunchImage.launchimage/Contents.json b/SwiftTutorial/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..c79ebd3 --- /dev/null +++ b/SwiftTutorial/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "subtype" : "retina4", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MusicPlayer/Info.plist b/SwiftTutorial/Info.plist similarity index 65% rename from MusicPlayer/Info.plist rename to SwiftTutorial/Info.plist index 4f04142..310bb7e 100644 --- a/MusicPlayer/Info.plist +++ b/SwiftTutorial/Info.plist @@ -5,13 +5,13 @@ CFBundleDevelopmentRegion en CFBundleExecutable - $(EXECUTABLE_NAME) + ${EXECUTABLE_NAME} CFBundleIdentifier - com.jqsoftware.$(PRODUCT_NAME:rfc1034identifier) + com.jqsoftware.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName - $(PRODUCT_NAME) + ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleShortVersionString @@ -22,19 +22,11 @@ 1 LSRequiresIPhoneOS - UILaunchStoryboardName - LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - diff --git a/SwiftTutorial/SearchResultsViewController.swift b/SwiftTutorial/SearchResultsViewController.swift new file mode 100644 index 0000000..44b5e4f --- /dev/null +++ b/SwiftTutorial/SearchResultsViewController.swift @@ -0,0 +1,172 @@ +// +// ViewController.swift +// SwiftTutorial +// +// Created by Jameson Quave on 6/16/14. +// Copyright (c) 2014 JQ Software LLC. All rights reserved. +// + +import UIKit +import QuartzCore + +class SearchResultsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, APIControllerProtocol { + + @IBOutlet var appsTableView : UITableView + var albums: Album[] = [] + @lazy var api: APIController = APIController(delegate: self) + var imageCache = NSMutableDictionary() + let kCellIdentifier = "SearchResultCell" + + override func viewDidLoad() { + super.viewDidLoad() + UIApplication.sharedApplication().networkActivityIndicatorVisible = true + api.searchItunesFor("Bob Dylan") + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int { + return albums.count + } + + override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject) { + let detailsViewController: DetailsViewController = segue.destinationViewController as DetailsViewController + let albumIndex = appsTableView.indexPathForSelectedRow().row + let selectedAlbum = self.albums[albumIndex] + detailsViewController.album = selectedAlbum + } + + func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { + + let cell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as UITableViewCell + + // Find this cell's album by passing in the indexPath.row to the subscript method for an array of type Album[] + let album = self.albums[indexPath.row] + cell.text = album.title + cell.image = UIImage(named: "Blank52") + cell.detailTextLabel.text = album.price + + dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { + // Jump in to a background thread to get the image for this item + + // Grab the artworkUrl60 key to get an image URL for the app's thumbnail + //var urlString: NSString = rowData["artworkUrl60"] as NSString + let urlString = album.thumbnailImageURL + + // Check our image cache for the existing key. This is just a dictionary of UIImages + var image = self.imageCache[urlString!] as? UIImage + + if( !image? ) { + // If the image does not exist, we need to download it + let imgURL = NSURL(string: urlString) + + // Download an NSData representation of the image at the URL + let request: NSURLRequest = NSURLRequest(URL: imgURL) + let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self) + NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in + if !error? { + image = UIImage(data: data) + + // Store the image in to our cache + self.imageCache[urlString!] = image + + // Sometimes this request takes a while, and it's possible that a cell could be re-used before the art is done loading. + // Let's explicitly call the cellForRowAtIndexPath method of our tableView to make sure the cell is not nil, and therefore still showing onscreen. + // While this method sounds a lot like the method we're in right now, it isn't. + // Ctrl+Click on the method name to see how it's defined, including the following comment: + /** // returns nil if cell is not visible or index path is out of range **/ + if let albumArtsCell: UITableViewCell? = tableView.cellForRowAtIndexPath(indexPath) { + albumArtsCell!.image = image + } + } + else { + println("Error: \(error.localizedDescription)") + } + }) + + } + else { + cell.image = image + } + + + }) + return cell + } + + func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) { + /*// Get the row data for the selected row + var rowData: NSDictionary = self.tableData[indexPath.row] as NSDictionary + + var name: String = rowData["trackName"] as String + var formattedPrice: String = rowData["formattedPrice"] as String + + var alert: UIAlertView = UIAlertView() + alert.title = name + alert.message = formattedPrice + alert.addButtonWithTitle("Ok") + alert.show()*/ + } + + func didReceiveAPIResults(results: NSDictionary) { + // Store the results in our table data array + if results.count>0 { + + let allResults: NSDictionary[] = results["results"] as NSDictionary[] + + // Sometimes iTunes returns a collection, not a track, so we check both for the 'name' + for result: NSDictionary in allResults { + + var name: String? = result["trackName"] as? String + if !name? { + name = result["collectionName"] as? String + } + + // Sometimes price comes in as formattedPrice, sometimes as collectionPrice.. and sometimes it's a float instead of a string. Hooray! + var price: String? = result["formattedPrice"] as? String + if !price? { + price = result["collectionPrice"] as? String + if !price? { + var priceFloat: Float? = result["collectionPrice"] as? Float + var nf: NSNumberFormatter = NSNumberFormatter() + nf.maximumFractionDigits = 2; + if priceFloat? { + price = "$"+nf.stringFromNumber(priceFloat) + } + } + } + + let thumbnailURL: String? = result["artworkUrl60"] as? String + let imageURL: String? = result["artworkUrl100"] as? String + let artistURL: String? = result["artistViewUrl"] as? String + + var itemURL: String? = result["collectionViewUrl"] as? String + if !itemURL? { + itemURL = result["trackViewUrl"] as? String + } + + var collectionId = result["collectionId"] as? Int + var newAlbum = Album(name: name!, price: price!, thumbnailImageURL: thumbnailURL!, largeImageURL: imageURL!, itemURL: itemURL!, artistURL: artistURL!, collectionId: collectionId!) + albums.append(newAlbum) + } + + dispatch_async(dispatch_get_main_queue(), { + self.appsTableView.reloadData() + }) + + UIApplication.sharedApplication().networkActivityIndicatorVisible = false + } + } + + func tableView(tableView: UITableView!, willDisplayCell cell: UITableViewCell!, forRowAtIndexPath indexPath: NSIndexPath!) { + cell.layer.transform = CATransform3DMakeScale(0.1,0.1,1) + UIView.animateWithDuration(0.25, animations: { + cell.layer.transform = CATransform3DMakeScale(1,1,1) + }) + } + +} + diff --git a/SwiftTutorial/Track.swift b/SwiftTutorial/Track.swift new file mode 100644 index 0000000..a6548e4 --- /dev/null +++ b/SwiftTutorial/Track.swift @@ -0,0 +1,22 @@ +// +// Track.swift +// SwiftTutorial +// +// Created by Jameson Quave on 6/16/14. +// Copyright (c) 2014 JQ Software LLC. All rights reserved. +// + +import Foundation + +class Track { + + var title: String? + var price: String? + var previewUrl: String? + + init(dict: NSDictionary!) { + self.title = dict["trackName"] as? String + self.price = dict["trackPrice"] as? String + self.previewUrl = dict["previewUrl"] as? String + } +} \ No newline at end of file diff --git a/SwiftTutorial/TrackCell.swift b/SwiftTutorial/TrackCell.swift new file mode 100644 index 0000000..b98af27 --- /dev/null +++ b/SwiftTutorial/TrackCell.swift @@ -0,0 +1,14 @@ +// +// TrackCell.swift +// SwiftTutorial +// +// Created by Jameson Quave on 6/16/14. +// Copyright (c) 2014 JQ Software LLC. All rights reserved. +// + +import UIKit + +class TrackCell: UITableViewCell { + @IBOutlet var titleLabel : UILabel + @IBOutlet var playIcon : UILabel +} diff --git a/MusicPlayerTests/Info.plist b/SwiftTutorialTests/Info.plist similarity index 82% rename from MusicPlayerTests/Info.plist rename to SwiftTutorialTests/Info.plist index 8f1c5d1..a555585 100644 --- a/MusicPlayerTests/Info.plist +++ b/SwiftTutorialTests/Info.plist @@ -5,13 +5,13 @@ CFBundleDevelopmentRegion en CFBundleExecutable - $(EXECUTABLE_NAME) + ${EXECUTABLE_NAME} CFBundleIdentifier - com.jqsoftware.$(PRODUCT_NAME:rfc1034identifier) + com.jqsoftware.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName - $(PRODUCT_NAME) + ${PRODUCT_NAME} CFBundlePackageType BNDL CFBundleShortVersionString diff --git a/MusicPlayerTests/MusicPlayerTests.swift b/SwiftTutorialTests/SwiftTutorialTests.swift similarity index 84% rename from MusicPlayerTests/MusicPlayerTests.swift rename to SwiftTutorialTests/SwiftTutorialTests.swift index 4ee03d5..4633736 100644 --- a/MusicPlayerTests/MusicPlayerTests.swift +++ b/SwiftTutorialTests/SwiftTutorialTests.swift @@ -1,15 +1,14 @@ // -// MusicPlayerTests.swift -// MusicPlayerTests +// SwiftTutorialTests.swift +// SwiftTutorialTests // -// Created by Jameson Quave on 9/16/14. +// Created by Jameson Quave on 6/16/14. // Copyright (c) 2014 JQ Software LLC. All rights reserved. // -import UIKit import XCTest -class MusicPlayerTests: XCTestCase { +class SwiftTutorialTests: XCTestCase { override func setUp() { super.setUp()